refactor option handling (#1351)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Fri, 18 Oct 2024 21:23:22 +0000 (15:23 -0600)
committerGitHub <noreply@github.com>
Fri, 18 Oct 2024 21:23:22 +0000 (15:23 -0600)
* rough in Option class

* testo passes

* rough in OptionBool

* more OptionBool use

* more OptionBool

* fix isEmpty

* store qstrings

* dont return const

* rename

* convert a few lost ARGTYPE_BOOLs to OptionBool.

* utilize avalable QString for options.

* obsolete argvalptr

* Option is abstract class

* eliminate special handling of ARGTYPE_BOOL without default in vecs.

* fix #982 ...

garmin, ozi, xcsv mkshort options whitespace_ok, must_unique broken since 2006.

* test to make sure OptionBool iff ARGTYPE_BOOL

* use OptionBool for all ARGTYPE_BOOL options.

* correct OptionBool type.

* delete unused parameterized Option ctors.

* format and comment option.h

* nodiscard for class Option.

* vecs nullptr checks

* have Vecs::validate_args check argval isn't nullptr.

* catch up includes

* clarify comment

* fix introduced bug caught by tidy.

85 files changed:
arcdist.cc
arcdist.h
bend.h
defs.h
dg-100.cc
dg-100.h
discard.cc
discard.h
duplicate.h
exif.cc
exif.h
filter_vecs.cc
filter_vecs.h
garmin.cc
garmin.h
garmin_fit.cc
garmin_fit.h
garmin_gpi.cc
garmin_gpi.h
garmin_txt.cc
garmin_txt.h
garmin_xt.h
gdb.h
geo.cc
geo.h
geojson.h
globalsat_sport.cc
globalsat_sport.h
gpx.cc
gpx.h
gtrnctr.cc
gtrnctr.h
height.cc
height.h
html.h
igc.cc
igc.h
interpolate.cc
interpolate.h
kml.cc
kml.h
lowranceusr.cc
lowranceusr.h
mtk_logger.cc
mtk_logger.h
nmea.cc
nmea.h
nukedata.cc
nukedata.h
option.h [new file with mode: 0644]
osm.cc
osm.h
ozi.cc
ozi.h
polygon.cc
polygon.h
position.cc
position.h
radius.cc
radius.h
random.h
resample.h
shape.h
skytraq.cc
skytraq.h
smplrout.h
sort.h
stackfilter.h
subrip.cc
subrip.h
text.h
tpg.cc
tpg.h
trackfilter.cc
trackfilter.h
transform.cc
transform.h
unicsv.h
validate.cc
validate.h
vcf.h
vecs.cc
vecs.h
xcsv.cc
xcsv.h

index d213222d657d91e5940373ac3a0d23f6d5b96c5b..96760db9a3b676e3d8377942c6a3938248cd87b8 100644 (file)
@@ -24,6 +24,7 @@
 #include <cmath>                  // for round
 #include <cstdio>                 // for printf, sscanf
 #include <cstdlib>                // for strtod
+#include <tuple>                  // for tie, tuple
 
 #include <QByteArray>             // for QByteArray
 #include <QString>                // for QString
@@ -112,7 +113,7 @@ void ArcDistanceFilter::process()
     QString line;
 
     gpsbabel::TextStream stream;
-    stream.open(arcfileopt, QIODevice::ReadOnly, MYNAME);
+    stream.open(arcfileopt.get(), QIODevice::ReadOnly, MYNAME);
 
     auto* arcpt1 = new Waypoint;
     auto* arcpt2 = new Waypoint;
@@ -157,7 +158,7 @@ void ArcDistanceFilter::process()
     if (wp->extra_data) {
       auto* ed = (extra_data*) wp->extra_data;
       wp->extra_data = nullptr;
-      if ((ed->distance >= pos_dist) == (exclopt == nullptr)) {
+      if ((ed->distance >= pos_dist) == !exclopt) {
         wp->wpt_flags.marked_for_deletion = 1;
         removed++;
       } else if (projectopt) {
index 7e30e4e706a2b9d42ff11c38490406291a0ad607..47526788deb455d2d8fce89d9886ed4232fcbbba 100644 (file)
--- a/arcdist.h
+++ b/arcdist.h
 #ifndef ARCDIST_H_INCLUDED_
 #define ARCDIST_H_INCLUDED_
 
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
 #include "defs.h"    // for ARG_NOMINMAX, ARGTYPE_BOOL, Waypoint (ptr only)
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool, OptionCString
 
 #if FILTERS_ENABLED
 
@@ -58,13 +61,13 @@ private:
   /* Data Members */
 
   double pos_dist{};
-  char* distopt = nullptr;
-  char* arcfileopt = nullptr;
-  char* rteopt = nullptr;
-  char* trkopt = nullptr;
-  char* exclopt = nullptr;
-  char* ptsopt = nullptr;
-  char* projectopt = nullptr;
+  OptionCString distopt;
+  OptionCString arcfileopt;
+  OptionBool rteopt;
+  OptionBool trkopt;
+  OptionBool exclopt;
+  OptionBool ptsopt;
+  OptionBool projectopt;
 
   QVector<arglist_t> args = {
     {
diff --git a/bend.h b/bend.h
index 69cc59c7021e98085022233a98e9fef6da883246..73cf803e80bdf5f794489ea67adf416cf8804ab7 100644 (file)
--- a/bend.h
+++ b/bend.h
 #ifndef BEND_H_INCLUDED_
 #define BEND_H_INCLUDED_
 
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
 #include "defs.h"    // for route_head (ptr only), ARGTYPE_FLOAT, ARG_NOMINMAX
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionCString
 
 #if FILTERS_ENABLED
 
@@ -42,8 +45,8 @@ public:
   void deinit() override;
 
 private:
-  char* distopt = nullptr;
-  char* minangleopt = nullptr;
+  OptionCString distopt;
+  OptionCString minangleopt;
 
   double maxDist{};
   double minAngle{};
diff --git a/defs.h b/defs.h
index 84ecf4636d2f8fb070f7ba850c2a4eeda167f521..5a274924353f3e83baf0a2bb148dd6bc4a40e4f4 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -46,6 +46,7 @@
 #include "geocache.h"                // for Geocache
 #include "formspec.h"                // for FormatSpecificData
 #include "inifile.h"                 // for inifile_t
+#include "option.h"
 #include "session.h"                 // for session_t
 #include "src/core/datetime.h"       // for DateTime
 
@@ -873,13 +874,13 @@ extern posn_status tracking_status;
 
 struct arglist_t {
   const QString argstring;
-  char** const argval{nullptr};
+  Option* const argval{nullptr};
   const QString helpstring;
   const QString defaultvalue;
   const uint32_t argtype{ARGTYPE_UNKNOWN};
   const QString minvalue;    /* minimum value for numeric options */
   const QString maxvalue;    /* maximum value for numeric options */
-  char* argvalptr{nullptr};         /* !!! internal helper. Not used in definitions !!! */
+  char* unused{nullptr};     /* TODO: delete from initialization lists */
 };
 
 enum ff_type {
index 3279daeaebfbfc394229b8301df5e465943c1c04..5594ef24fdef1abc7779436101dd9eb7c6fcf6fc 100644 (file)
--- a/dg-100.cc
+++ b/dg-100.cc
@@ -692,12 +692,12 @@ Dg100Format::rd_deinit()
 void
 Dg100Format::read()
 {
-  if (*erase_only == '1') {
+  if (erase_only) {
     dg100_erase();
     return;
   }
   dg100_getfiles();
-  if (*erase == '1') {
+  if (erase) {
     dg100_erase();
   }
 }
index 346ea5ff4982ebc290cb5298fb11a089ec132a52..be51c8f5cd13ed5345b5119e8596ef19253c4eeb 100644 (file)
--- a/dg-100.h
+++ b/dg-100.h
 #ifndef DG100_H_INCLUDED_
 #define DG100_H_INCLUDED_
 
-#include <cstdint>           // for uint8_t, int16_t, uint16_t
-#include <cstdio>            // for size_t
+#include <cstdint>    // for uint8_t, int16_t, uint16_t
+#include <cstdio>     // for size_t
 
-#include <QDateTime>         // for QDateTime
-#include <QList>             // for QList
-#include <QString>           // for QString
-#include <QVector>           // for QVector
+#include <QDateTime>  // for QDateTime
+#include <QList>      // for QList
+#include <QString>    // for QString
+#include <QVector>    // for QVector
 
 #include "defs.h"
-#include "format.h"          // for Format
-#include "gbfile.h"          // for gbfile
+#include "format.h"   // for Format
+#include "gbfile.h"   // for gbfile
+#include "option.h"   // for OptionBool
 
 
 class Dg100Format : public Format
@@ -141,8 +142,8 @@ protected:
 
   /* GPSBabel integration */
 
-  char* erase{nullptr};
-  char* erase_only{nullptr};
+  OptionBool erase;
+  OptionBool erase_only;
 
   QVector<arglist_t> dg100_args = {
     {
index 47fecbdf61a10e03240e29d75d4fb2325ef287cc..34ea92258ca335bd1c194463351c5204ca918a58 100644 (file)
@@ -157,25 +157,25 @@ void DiscardFilter::init()
   }
 
   if (nameopt) {
-    name_regex = generateRegExp(nameopt);
+    name_regex = generateRegExp(nameopt.get());
     if (!name_regex.isValid()) {
       fatal(FatalMsg() << "discard: matchname option is an invalid expression.");
     }
   }
   if (descopt) {
-    desc_regex = generateRegExp(descopt);
+    desc_regex = generateRegExp(descopt.get());
     if (!desc_regex.isValid()) {
       fatal(FatalMsg() << "discard: matchdesc option is an invalid expression.");
     }
   }
   if (cmtopt) {
-    cmt_regex = generateRegExp(cmtopt);
+    cmt_regex = generateRegExp(cmtopt.get());
     if (!cmt_regex.isValid()) {
       fatal(FatalMsg() << "discard: matchcmt option is an invalid expression.");
     }
   }
   if (iconopt) {
-    icon_regex = generateRegExp(iconopt);
+    icon_regex = generateRegExp(iconopt.get());
     if (!icon_regex.isValid()) {
       fatal(FatalMsg() << "discard: matchicon option is an invalid expression.");
     }
index ac0a381dbcb64008cb2b901280ccf925579b1247..1325d26002a167dc0347e3eb1eddaa3b5be327b9 100644 (file)
--- a/discard.h
+++ b/discard.h
 #ifndef DISCARD_H_INCLUDED_
 #define DISCARD_H_INCLUDED_
 
+#include <QList>               // for QList
 #include <QRegularExpression>  // for QRegularExpression
 #include <QString>             // for QString
 #include <QVector>             // for QVector
 
 #include "defs.h"              // for arglist_t, ARG_NOMINMAX, ARGTYPE_BEGIN_REQ, ARGTYPE_STRING, ARGTYPE_BOOL, ARGTYPE_INT, ARGTYPE_FLOAT, route_head, ARGTYPE_END_REQ, Waypoint, gpsdata_type
 #include "filter.h"            // for Filter
+#include "option.h"            // for OptionCString, OptionBool
 
 #if FILTERS_ENABLED
 class DiscardFilter:public Filter
@@ -48,21 +50,21 @@ private:
 
   /* Data Members */
 
-  char* hdopopt = nullptr;
-  char* vdopopt = nullptr;
-  char* andopt = nullptr;
-  char* satopt = nullptr;
-  char* fixnoneopt = nullptr;
-  char* fixunknownopt = nullptr;
-  char* eleminopt = nullptr;
-  char* elemaxopt = nullptr;
-  char* nameopt = nullptr;
+  OptionCString hdopopt;
+  OptionCString vdopopt;
+  OptionBool andopt;
+  OptionCString satopt;
+  OptionBool fixnoneopt;
+  OptionBool fixunknownopt;
+  OptionCString eleminopt;
+  OptionCString elemaxopt;
+  OptionCString nameopt;
   QRegularExpression name_regex;
-  char* descopt = nullptr;
+  OptionCString descopt;
   QRegularExpression desc_regex;
-  char* cmtopt = nullptr;
+  OptionCString cmtopt;
   QRegularExpression cmt_regex;
-  char* iconopt = nullptr;
+  OptionCString iconopt;
   QRegularExpression icon_regex;
 
   double hdopf{};
index d8d165209ca75fb87049103a7e317ba12cda77e6..16e063ea51339df298e136d2e1941ec0171b6e86 100644 (file)
 #ifndef DUPLICATE_H_INCLUDED_
 #define DUPLICATE_H_INCLUDED_
 
+#include <QList>     // for QList
 #include <QString>   // for QString
 #include <QVector>   // for QVector
 
 #include "defs.h"    // for ARGTYPE_BOOL, ARG_NOMINMAX, Waypoint (ptr only)
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool
 
 #if FILTERS_ENABLED
 
@@ -41,10 +43,10 @@ public:
   void process() override;
 
 private:
-  char* snopt = nullptr;
-  char* lcopt = nullptr;
-  char* purge_duplicates = nullptr;
-  char* correct_coords = nullptr;
+  OptionBool snopt;
+  OptionBool lcopt;
+  OptionBool purge_duplicates;
+  OptionBool correct_coords;
 
   QVector<arglist_t> args = {
     {
diff --git a/exif.cc b/exif.cc
index 624f5b4edeea69fc610c2a1fd8b5240858e7f266..e38714cffc8a6f78d6dab23a979c52b967ddbebc 100644 (file)
--- a/exif.cc
+++ b/exif.cc
@@ -1178,7 +1178,7 @@ ExifFormat::exif_find_wpt_by_name(const Waypoint* wpt)
 {
   if (exif_wpt_ref != nullptr) {
     return;
-  } else if ((wpt->shortname != nullptr) && (case_ignore_strcmp(wpt->shortname, opt_name) == 0)) {
+  } else if ((wpt->shortname != nullptr) && (case_ignore_strcmp(wpt->shortname, opt_name.get()) == 0)) {
     exif_wpt_ref = wpt;
   }
 }
@@ -1502,7 +1502,7 @@ ExifFormat::wr_deinit()
   gbfclose(fout_);
 
   if (exif_success) {
-    if (*opt_overwrite == '1') {
+    if (opt_overwrite) {
       QFile::remove(exif_fout_name);
       QFile::rename(tmpname, exif_fout_name);
     }
@@ -1530,7 +1530,7 @@ ExifFormat::write()
       track_disp_all(nullptr, nullptr, exif_find_wpt_by_name_lambda);
     }
     if (exif_wpt_ref == nullptr) {
-      warning(MYNAME ": No matching point with name \"%s\" found.\n", opt_name);
+      warning(MYNAME ": No matching point with name \"%s\" found.\n", qPrintable(opt_name.get()));
     }
   } else {
     auto exif_find_wpt_by_time_lambda = [this](const Waypoint* waypointp)->void {
diff --git a/exif.h b/exif.h
index 2be58dedaf4333b159ed83d5e8b044a8934e73ca..e6ac7409d7c092cc642cf405b97f517b7aea91ee 100644 (file)
--- a/exif.h
+++ b/exif.h
 #ifndef EXIF_H_INCLUDED_
 #define EXIF_H_INCLUDED_
 
-#include <QDate>      // for QDate
-#include <QDateTime>  // for QDateTime
-#include <QList>      // for QList
-#include <QString>    // for QString
-#include <QTime>      // for QTime
-#include <QVariant>   // for QVariant
-#include <QVector>    // for QVector
+#include <QByteArray>  // for QByteArray
+#include <QDate>       // for QDate
+#include <QDateTime>   // for QDateTime
+#include <QList>       // for QList
+#include <QString>     // for QString
+#include <QTime>       // for QTime
+#include <QVariant>    // for QVariant
+#include <QVector>     // for QVector
 
-#include <cstdint>    // for uint32_t, uint16_t, uint8_t, int16_t, int32_t
+#include <cstdint>     // for uint32_t, uint16_t, uint8_t, int16_t, int32_t
 
-#include "defs.h"     // for arglist_t, ff_cap, Waypoint, ARG_NOMINMAX, ARGTYPE_BOOL, ff_cap_none, ARGTYPE_INT, ARGTYPE_STRING, ff_cap_read, ff_cap_write, ff_type, ff_type_file
-#include "format.h"   // for Format
-#include "gbfile.h"   // for gbfile, gbsize_t
+#include "defs.h"      // for arglist_t, ff_cap, Waypoint, ARG_NOMINMAX, ARGTYPE_BOOL, ff_cap_none, ARGTYPE_INT, ARGTYPE_STRING, ff_cap_read, ff_cap_write, ff_type, ff_type_file
+#include "format.h"    // for Format
+#include "gbfile.h"    // for gbfile, gbsize_t
+#include "option.h"    // for OptionCString, OptionBool
 
 
 class ExifFormat : public Format
@@ -201,11 +203,11 @@ private:
   char exif_success{};
   QString exif_fout_name;
 
-  char* opt_filename{};
-  char* opt_overwrite{};
-  char* opt_frame{};
-  char* opt_name{};
-  char* opt_offsettime{};
+  OptionBool opt_filename;
+  OptionBool opt_overwrite;
+  OptionCString opt_frame;
+  OptionCString opt_name;
+  OptionCString opt_offsettime;
 
   QVector<arglist_t> exif_args = {
     { "filename", &opt_filename, "Set waypoint name to source filename", "Y", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr },
index ccb2e1a6b618482ffe5079953965fc8c9b14af0f..6be8c048f2de4409d1f8fb99264079f2c8133a07 100644 (file)
@@ -31,6 +31,7 @@
 #include <algorithm>        // for sort
 #include <cassert>          // for assert
 #include <cstdio>           // for printf
+#include <type_traits>      // for is_base_of
 
 #include "arcdist.h"        // for ArcDistanceFilter
 #include "bend.h"           // for BendFilter
@@ -216,9 +217,9 @@ void FilterVecs::prepare_filter(const fltinfo_t& fltdata)
         qtemp = inifile_readstr(global_opts.inifile, "Common filter settings", arg.argstring);
       }
       if (qtemp.isNull()) {
-        Vecs::assign_option(fltdata.fltname, &arg, arg.defaultvalue);
+        Vecs::assign_option(fltdata.fltname, arg, arg.defaultvalue);
       } else {
-        Vecs::assign_option(fltdata.fltname, &arg, qtemp);
+        Vecs::assign_option(fltdata.fltname, arg, qtemp);
       }
     }
   }
@@ -230,7 +231,7 @@ void FilterVecs::prepare_filter(const fltinfo_t& fltdata)
       for (auto& arg : *args) {
         const QString opt = Vecs::get_option(fltdata.options, arg.argstring);
         if (!opt.isNull()) {
-          Vecs::assign_option(fltdata.fltname, &arg, opt);
+          Vecs::assign_option(fltdata.fltname, arg, opt);
         }
       }
     }
@@ -274,9 +275,6 @@ void FilterVecs::init_filter_vec(Filter* flt)
   QVector<arglist_t>* args = flt->get_args();
   if (args && !args->isEmpty()) {
     assert(args->isDetached());
-    for (auto& arg : *args) {
-      arg.argvalptr = nullptr;
-    }
   }
 }
 
index beaaf0c3e655f0242b08b0cd200605eda5eb2a5d..7f9b8db7387d2b8144be99e6a007ec3a17b95648 100644 (file)
 #ifndef FILTER_VECS_H_INCLUDED_
 #define FILTER_VECS_H_INCLUDED_
 
-#include <QString>          // for QString
+#include <QList>        // for QList
+#include <QString>      // for QString
+#include <QStringList>  // for QStringList
 
-#include "defs.h"           // for arglist_t
-#include "filter.h"         // for Filter
+#include "defs.h"       // for arglist_t
+#include "filter.h"     // for Filter
 
 
 class FilterVecs
index 13012f5eeebe963de0d3577bde0417eed8420a96..fffc175ca408163108e03e61676c8409324f439f 100644 (file)
--- a/garmin.cc
+++ b/garmin.cc
@@ -205,7 +205,7 @@ GarminFormat::rw_init(const QString& fname)
     case 786: /* HC model */
     case 957: /* Legend HC */
       receiver_short_length = 14;
-      snwhiteopt = xstrdup("1");
+      snwhiteopt.set("1");
       receiver_must_upper = false;
       /* This might be 8859-1 */
       receiver_charset = "windows-1252";
@@ -263,8 +263,8 @@ GarminFormat::rw_init(const QString& fname)
     mkshort_handle->set_length(receiver_short_length);
   }
 
-  if (snwhiteopt) {
-    mkshort_handle->set_whitespace_ok(xstrtoi(snwhiteopt, nullptr, 10));
+  if (snwhiteopt.has_value()) {
+    mkshort_handle->set_whitespace_ok(snwhiteopt);
   }
 
   /*
@@ -849,7 +849,7 @@ GarminFormat::waypoint_prepare()
     tx_waylist[i]->lat = wpt->latitude;
 
     if (deficon) {
-      icon = gt_find_icon_number_from_desc(deficon, PCX);
+      icon = gt_find_icon_number_from_desc(deficon.get(), PCX);
     } else {
       if (!wpt->gc_data->get_icon().isEmpty()) {
         icon = gt_find_icon_number_from_desc(wpt->gc_data->get_icon(), PCX);
index 68d42bbfbcdf4557f1a7655ff425165097c4f004..a4f27aef5ce15178e74e538254007678deb5c86e 100644 (file)
--- a/garmin.h
+++ b/garmin.h
 #ifndef GARMIN_H_INCLUDED_
 #define GARMIN_H_INCLUDED_
 
-#include <cstdio>              // for size_t
+#include <cstdio>             // for size_t
 
-#include <QByteArray>          // for QByteArray
-#include <QString>             // for QString
-#include <QTextCodec>          // for QTextCodec
-#include <QVector>             // for QVector
+#include <QList>              // for QList
+#include <QByteArray>         // for QByteArray
+#include <QString>            // for QString
+#include <QTextCodec>         // for QTextCodec
+#include <QVector>            // for QVector
 
 #include "defs.h"
-#include "format.h"            // for Format
-#include "jeeps/gpsdevice.h"   // for gpsdevh
-#include "jeeps/gpssend.h"     // for GPS_PWay, GPS_SWay, GPS_PTrack, GPS_PPvt_Data, GPS_SLap
-#include "mkshort.h"           // for MakeShort
+#include "format.h"           // for Format
+#include "jeeps/gpsdevice.h"  // for gpsdevh
+#include "jeeps/gpssend.h"    // for GPS_PWay, GPS_SWay, GPS_PTrack, GPS_PPvt_Data, GPS_SLap
+#include "mkshort.h"          // for MakeShort
+#include "option.h"           // for OptionCString, OptionBool
 
 
 class GarminFormat : public Format
@@ -118,17 +120,17 @@ private:
   GPS_PTrack* tx_tracklist{};
   GPS_PTrack* cur_tx_tracklist_entry{};
   int my_track_count = 0;
-  char* getposn = nullptr;
-  char* poweroff = nullptr;
-  char* eraset = nullptr;
-  char* resettime = nullptr;
-  char* snlen = nullptr;
-  char* snwhiteopt = nullptr;
-  char* deficon = nullptr;
-  char* category = nullptr;
-  char* categorybitsopt = nullptr;
-  char* baudopt = nullptr;
-  char* opt_codec = nullptr;
+  OptionBool getposn;
+  OptionBool poweroff;
+  OptionBool eraset;
+  OptionBool resettime;
+  OptionCString snlen;
+  OptionBool snwhiteopt;
+  OptionCString deficon;
+  OptionCString category;
+  OptionCString categorybitsopt;
+  OptionCString baudopt;
+  OptionCString opt_codec;
   int baud = 0;
   int categorybits{};
   bool receiver_must_upper = true;
index d7eda3600920c761f6a8430c4bcc8940058042ce..a2061d95ac8a43536d42e4836e4a28d25789eb87 100644 (file)
@@ -25,7 +25,6 @@
 #include <cstdint>             // for uint8_t, uint16_t, uint32_t, int32_t, int8_t, uint64_t
 #include <cstdio>              // for EOF, SEEK_SET, snprintf
 #include <deque>               // for deque, _Deque_iterator, operator!=
-#include <memory>              // for allocator_traits<>::value_type
 #include <string>              // for operator+, to_string, char_traits
 #include <utility>             // for pair
 #include <vector>              // for vector
index 6336f541ec2389d5971f3338ef8360f396086b8e..d0d9cf61a94b6bdf7c87955f41f435207bc90818 100644 (file)
@@ -39,6 +39,7 @@
 #include "defs.h"
 #include "format.h"             // for Format
 #include "gbfile.h"             // for gbfile
+#include "option.h"             // for OptionBool
 #include "src/core/datetime.h"  // for DateTime
 
 
@@ -258,8 +259,8 @@ private:
 
   /* Data Members */
 
-  char* opt_allpoints = nullptr;
-  char* opt_recoverymode = nullptr;
+  OptionBool opt_allpoints;
+  OptionBool opt_recoverymode;
   int lap_ct = 0;
   bool new_trkseg = false;
   bool write_header_msgs = false;
index 3d0ee03321dfcb3c004c9115df7d51b573f0e1b0..8cfd2365357995f961c456725f2cba46d1fb9cfa 100644 (file)
@@ -980,7 +980,7 @@ GarminGPIFormat::write_category(const char* /*unused*/, const unsigned char* ima
 {
   int sz = wdata_compute_size(wdata);
   sz += 8;  /* string header */
-  sz += str_from_unicode(QString::fromUtf8(opt_cat)).size();
+  sz += str_from_unicode(opt_cat.get()).size();
 
   gbfputint32(0x80009, fout);
   if ((! opt_hide_bitmap) && image_sz) {
@@ -989,7 +989,7 @@ GarminGPIFormat::write_category(const char* /*unused*/, const unsigned char* ima
     gbfputint32(sz, fout);
   }
   gbfputint32(sz, fout);
-  write_string(str_from_unicode(QString::fromUtf8(opt_cat)), 1);
+  write_string(str_from_unicode(opt_cat.get()), 1);
 
   wdata_write(wdata);
 
@@ -1044,7 +1044,7 @@ GarminGPIFormat::enum_waypt_cb(const Waypoint* ref) const
 
   auto* wpt = new Waypoint(*ref);
 
-  if (*opt_unique == '1') {
+  if (opt_unique) {
     wpt->shortname = short_h->mkshort(wpt->shortname);
   }
 
@@ -1275,11 +1275,11 @@ GarminGPIFormat::wr_init(const QString& fname)
   }
 
   if (! codepage) {
-    warning(MYNAME ": Unsupported character set (%s)!\n", opt_writecodec);
+    warning(MYNAME ": Unsupported character set (%s)!\n", qPrintable(opt_writecodec.get()));
     fatal(MYNAME ": Valid values are windows-1250 to windows-1257 and utf8.\n");
   }
 
-  codec = get_codec(opt_writecodec);
+  codec = get_codec(opt_writecodec.getba());
 
   units = tolower(opt_units[0]);
   if ((units != 'm') && (units != 's')) {
index cdc972eb38d960fd9419cf80a9093d76fa4c034f..0efbf81b70c58172f55fb2cb49c74c623d23a09f 100644 (file)
@@ -60,6 +60,7 @@
 #include "garmin_fs.h"  // for garmin_fs_t
 #include "gbfile.h"     // for gbfile
 #include "mkshort.h"    // for MakeShort
+#include "option.h"     // for OptionCString, OptionBool
 
 
 class GarminGPIFormat : public Format
@@ -307,10 +308,20 @@ private:
 
   /* Data Members */
 
-  char* opt_cat{}, *opt_pos{}, *opt_notes{}, *opt_hide_bitmap{}, *opt_descr{}, *opt_bitmap{};
-  char* opt_unique{}, *opt_alerts{}, *opt_units{}, *opt_speed{}, *opt_proximity{}, *opt_sleep{};
-  char* opt_lang{};
-  char* opt_writecodec{};
+  OptionCString opt_cat;
+  OptionBool opt_pos;
+  OptionBool opt_notes;
+  OptionBool opt_hide_bitmap;
+  OptionBool opt_descr;
+  OptionCString opt_bitmap;
+  OptionBool opt_unique;
+  OptionBool opt_alerts;
+  OptionCString opt_units;
+  OptionCString opt_speed;
+  OptionCString opt_proximity;
+  OptionCString opt_sleep;
+  OptionCString opt_lang;
+  OptionCString opt_writecodec;
   double defspeed{}, defproximity{};
   int alerts{};
 
index 1ed008080522e32c763ef902941d038672ffc88d..455fced792115a289115bbb696677d89c4d0696b 100644 (file)
@@ -637,7 +637,7 @@ void
 GarminTxtFormat::garmin_txt_utc_option()
 {
   if (opt_utc != nullptr) {
-    if (case_ignore_strcmp(opt_utc, "utc") == 0) {
+    if (case_ignore_strcmp(opt_utc.get(), "utc") == 0) {
       utc_offs = 0;
     } else {
       utc_offs = xstrtoi(opt_utc, nullptr, 10);
@@ -669,7 +669,7 @@ GarminTxtFormat::wr_init(const QString& fname)
   if (opt_precision) {
     precision = xstrtoi(opt_precision, nullptr, 10);
     if (precision < 0) {
-      fatal(MYNAME ": Invalid precision (%s)!", opt_precision);
+      fatal(MYNAME ": Invalid precision (%s)!", qPrintable(opt_precision.get()));
     }
   }
 
index 2b815b475f094551bad02de2f3fae4bb2ffddeb1..8c29c2924b32b78f2862bcd79bb8f90bc420579a 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "defs.h"
 #include "format.h"               // for Format
+#include "option.h"               // for OptionCString
 #include "src/core/textstream.h"  // for TextStream
 
 
@@ -172,14 +173,14 @@ private:
   std::array<QList<std::pair<QString, int>>, unknown_header> header_mapping_info;
   QStringList header_column_names;
 
-  char* opt_datum = nullptr;
-  char* opt_dist = nullptr;
-  char* opt_temp = nullptr;
-  char* opt_date_format = nullptr;
-  char* opt_time_format = nullptr;
-  char* opt_precision = nullptr;
-  char* opt_utc = nullptr;
-  char* opt_grid = nullptr;
+  OptionCString opt_datum;
+  OptionCString opt_dist;
+  OptionCString opt_temp;
+  OptionCString opt_date_format;
+  OptionCString opt_time_format;
+  OptionCString opt_precision;
+  OptionCString opt_utc;
+  OptionCString opt_grid;
 
   QVector<arglist_t> garmin_txt_args = {
     {"date",  &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr},
index 39c5b44c24f78faf430e71ec0f5120247b29223c..645b9928b3448c9089e2c113da7e451ddd71109a 100644 (file)
 
 #include <cstdint>   // for uint8_t, uint16_t, uint32_t
 
+#include <QList>     // for QList
 #include <QString>   // for QString
 #include <QVector>   // for QVector
 
 #include "defs.h"
 #include "format.h"  // for Format
 #include "gbfile.h"  // for gbfile
+#include "option.h"  // for OptionCString
 
 
 class GarminXTFormat : public Format
@@ -92,8 +94,8 @@ private:
 
   gbfile* fin{};
   route_head* track{};
-  char*        opt_xt_ftype = nullptr;
-  char*        opt_trk_header = nullptr;
+  OptionCString        opt_xt_ftype;
+  OptionCString        opt_trk_header;
 
   QVector<arglist_t> format_garmin_xt_args = {
     {"ftype", &opt_xt_ftype, "Garmin Mobile XT ([ATRK]/STRK)", "ATRK", ARGTYPE_STRING | ARGTYPE_REQUIRED, ARG_NOMINMAX, nullptr},
diff --git a/gdb.h b/gdb.h
index d4797a45ebc75a0584b789ae3d7221708e2ee800..87920c888b7e0c1d29f8109d8069989c3346bd85 100644 (file)
--- a/gdb.h
+++ b/gdb.h
@@ -26,6 +26,7 @@
 #ifndef GDB_H_INCLUDED_
 #define GDB_H_INCLUDED_
 
+#include <QList>            // for QList
 #include <QHash>            // for QHash<>::const_iterator, QHash<>::key_iterator, qHash, qHashMulti, QHash
 #include <QString>          // for QString
 #include <QStringView>      // for QStringView
@@ -37,6 +38,7 @@
 #include "garmin_tables.h"  // for gt_waypt_classes_e
 #include "gbfile.h"         // for gbfile
 #include "mkshort.h"        // for MakeShort
+#include "option.h"         // for OptionBool, OptionCString
 
 
 class GdbFormat : public Format
@@ -160,12 +162,12 @@ private:
   WptNamePosnHash waypt_nameposn_out_hash;
   MakeShort* short_h{};
 
-  char* gdb_opt_category{};
-  char* gdb_opt_ver{};
-  char* gdb_opt_via{};
-  char* gdb_opt_roadbook{};
-  char* gdb_opt_bitcategory{};
-  char* gdb_opt_drop_hidden_wpt{};
+  OptionCString gdb_opt_category;
+  OptionCString gdb_opt_ver;
+  OptionBool gdb_opt_via;
+  OptionBool gdb_opt_roadbook;
+  OptionCString gdb_opt_bitcategory;
+  OptionBool gdb_opt_drop_hidden_wpt;
 
   int waypt_flag{};
   int route_flag{};
diff --git a/geo.cc b/geo.cc
index 15eab8623a44b8b7d0ed8636ec927769e8c6234a..caf8b674a2b207f9150d9d415392093f96b10eb7 100644 (file)
--- a/geo.cc
+++ b/geo.cc
@@ -149,7 +149,7 @@ void GeoFormat::geo_waypt_pr(const Waypoint* waypointp, QXmlStreamWriter& writer
   writer.writeAttribute(QStringLiteral("lon"), QString::number(waypointp->longitude, 'f'));
   writer.writeEndElement();
 
-  writer.writeTextElement(QStringLiteral("type"), deficon ? deficon : waypointp->icon_descr);
+  writer.writeTextElement(QStringLiteral("type"), deficon ? deficon.get() : waypointp->icon_descr);
 
   if (waypointp->HasUrlLink()) {
     writer.writeStartElement(QStringLiteral("link"));
diff --git a/geo.h b/geo.h
index 96b31f492c9726a3bf49c3cf0224415b59d763ba..dac3cf4d469e5ac9d2499ff7c1304afb5585d135 100644 (file)
--- a/geo.h
+++ b/geo.h
@@ -27,6 +27,7 @@
 #include "defs.h"
 #include "format.h"          // for Format
 #include "geocache.h"        // for Geocache, Geocache::container_t
+#include "option.h"          // for OptionBool, OptionCString
 
 
 class GeoFormat : public Format
@@ -66,8 +67,8 @@ private:
 
   /* Data Members */
 
-  char* deficon = nullptr;
-  char* nuke_placer{};
+  OptionCString deficon;
+  OptionBool nuke_placer;
 
   QVector<arglist_t> geo_args = {
     {"deficon", &deficon, "Default icon name", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
index bcb9b20a7f66671c1e78b47bc6608b437453c76b..38cf471f28402edac366e1a0b2b8e9423a4a738b 100644 (file)
--- a/geojson.h
+++ b/geojson.h
 #ifndef GEOJSON_H_INCLUDED_
 #define GEOJSON_H_INCLUDED_
 
-#include <QJsonArray>                // for QJsonArray
-#include <QJsonObject>               // for QJsonObject
-#include <QString>                   // for QString, QStringLiteral
-#include <QVector>                   // for QVector
+#include <QList>            // for QList
+#include <QJsonArray>       // for QJsonArray
+#include <QJsonObject>      // for QJsonObject
+#include <QString>          // for QString, QStringLiteral
+#include <QVector>          // for QVector
 
 #include "defs.h"
-#include "format.h"                  // for Format
-#include "src/core/file.h"
+#include "format.h"         // for Format
+#include "option.h"         // for OptionBool
+#include "src/core/file.h"  // for File
 
 class GeoJsonFormat : public Format
 {
@@ -70,7 +72,7 @@ private:
   gpsbabel::File* ifd{nullptr};
   gpsbabel::File* ofd{nullptr};
   const char* MYNAME = "geojson";
-  char* compact_opt = nullptr;
+  OptionBool compact_opt;
   QJsonObject* track_object = nullptr;
   QJsonArray* track_coords = nullptr;
 
index e4a69c383cad740d93e18a3a4a3e8a17337045b6..c4a731b6740c5c9e8382711708422d6130a3ab19 100644 (file)
@@ -268,12 +268,12 @@ GlobalsatSportFormat::rd_init(const QString& fname)
     printf(MYNAME " rd_init()\n");
   }
   if (opt_dump_file) {
-    dumpfile = gbfopen(opt_dump_file, "wb", MYNAME);
+    dumpfile = gbfopen(opt_dump_file.get(), "wb", MYNAME);
     if (!dumpfile) {
-      printf(MYNAME " rd_init() creating dumpfile %s FAILED continue anyway\n", opt_dump_file);
+      printf(MYNAME " rd_init() creating dumpfile %s FAILED continue anyway\n", qPrintable(opt_dump_file.get()));
     } else {
       if (global_opts.debug_level > 1) {
-        printf(MYNAME " rd_init() creating dumpfile %s for writing binary copy of serial stream\n", opt_dump_file);
+        printf(MYNAME " rd_init() creating dumpfile %s for writing binary copy of serial stream\n", qPrintable(opt_dump_file.get()));
       }
     }
   }
@@ -288,11 +288,11 @@ GlobalsatSportFormat::rd_init(const QString& fname)
 
   }
   if (opt_timezone) {
-    if (QTimeZone::isTimeZoneIdAvailable(opt_timezone)) {
-      timezn = new QTimeZone(opt_timezone);
+    if (QTimeZone::isTimeZoneIdAvailable(opt_timezone.getba())) {
+      timezn = new QTimeZone(opt_timezone.getba());
     } else {
       list_timezones();
-      fatal(MYNAME ": Requested time zone \"%s\" not available.\n", opt_timezone);
+      fatal(MYNAME ": Requested time zone \"%s\" not available.\n", qPrintable(opt_timezone.get()));
     }
   } else {
     timezn = nullptr;
index 6a2586f36f61b96368c6e1d1a4d6318874425a06..1e7c59853ad0a4fb910ccd304d89ea55caec6825 100644 (file)
 #ifndef GLOBALSATSPORT_H_INCLUDED_
 #define GLOBALSATSPORT_H_INCLUDED_
 
-#include <cstdint>           // for uint32_t, uint8_t, uint16_t, int16_t
+#include <cstdint>    // for uint32_t, uint8_t, uint16_t, int16_t
 
-#include <QString>           // for QString
-#include <QTimeZone>         // for QTimeZone
-#include <QVector>           // for QVector
+#include <QList>      // for QList
+#include <QString>    // for QString
+#include <QTimeZone>  // for QTimeZone
+#include <QVector>    // for QVector
 
 #include "defs.h"
-#include "format.h"          // for Format
-#include "gbfile.h"          // for gbfclose, gbfopen, gbfread, gbfwrite, gbfile
+#include "format.h"   // for Format
+#include "gbfile.h"   // for gbfclose, gbfopen, gbfread, gbfwrite, gbfile
+#include "option.h"   // for OptionCString, OptionBool
 
 
 class GlobalsatSportFormat : public Format
@@ -227,12 +229,12 @@ private:
   void* serial_handle{nullptr};
   bool isSizeSwapped{false};
 
-  char* showlist{nullptr};               // if true show a list instead of download tracks
-  char* track{nullptr};                  // if not 0 only download this track, if 0 download all
+  OptionBool showlist;                  // if true show a list instead of download tracks
+  OptionCString track;                  // if not 0 only download this track, if 0 download all
 
-  char* opt_dump_file{nullptr};          // dump raw data to this file (optional)
-  char* opt_input_dump_file{nullptr};    // if true input is from a dump-file instead of serial console
-  char* opt_timezone{nullptr};
+  OptionCString opt_dump_file;          // dump raw data to this file (optional)
+  OptionBool opt_input_dump_file;       // if true input is from a dump-file instead of serial console
+  OptionCString opt_timezone;
   gbfile* dumpfile{nullptr};             // used for creating bin/RAW datadump files, useful for testing
   gbfile* in_file{nullptr};              // used for reading from bin/RAW datadump files, useful for testing
   QTimeZone* timezn{nullptr};
diff --git a/gpx.cc b/gpx.cc
index 080ad56598300c2cddd66735e2eef89229a44a2a..44d8f802b1c45e8996031bcad2d3705a6428bf27 100644 (file)
--- a/gpx.cc
+++ b/gpx.cc
@@ -986,7 +986,7 @@ GpxFormat::wr_init(const QString& fname)
   */
 
   if (opt_gpxver != nullptr) {
-    gpx_write_version = QVersionNumber::fromString(opt_gpxver).normalized();
+    gpx_write_version = QVersionNumber::fromString(opt_gpxver.get()).normalized();
   } else if (!gpx_highest_version_read.isNull()) {
     gpx_write_version = gpx_highest_version_read;
   } else {
diff --git a/gpx.h b/gpx.h
index 741c91bb873a1ed09fc2bc4ccb31b216f8a14406..99a1567e264a481133cbb870794020070ca084b4 100644 (file)
--- a/gpx.h
+++ b/gpx.h
@@ -35,6 +35,7 @@
 #include "format.h"                    // for Format
 #include "formspec.h"                  // for FormatSpecificData
 #include "mkshort.h"                   // for MakeShort
+#include "option.h"                    // for OptionBool, OptionCString
 #include "src/core/file.h"             // for File
 #include "src/core/xmlstreamwriter.h"  // for XmlStreamWriter
 #include "src/core/xmltag.h"           // for xml_tag
@@ -254,10 +255,10 @@ private:
   QXmlStreamReader* reader{};
   XmlTag* cur_tag{};
   QString cdatastr;
-  char* opt_logpoint = nullptr;
-  char* opt_humminbirdext = nullptr;
-  char* opt_garminext = nullptr;
-  char* opt_elevation_precision = nullptr;
+  OptionBool opt_logpoint;
+  OptionBool opt_humminbirdext;
+  OptionBool opt_garminext;
+  OptionCString opt_elevation_precision;
   int logpoint_ct = 0;
   int elevation_precision{};
 
@@ -265,7 +266,7 @@ private:
   const QVersionNumber gpx_1_0 = QVersionNumber(1,0).normalized();
   const QVersionNumber gpx_1_1 = QVersionNumber(1,1).normalized();
   QVersionNumber gpx_highest_version_read;
-  char* opt_gpxver = nullptr;
+  OptionCString opt_gpxver;
   QVersionNumber gpx_write_version;
   QXmlStreamAttributes gpx_namespace_attribute;
 
@@ -284,9 +285,9 @@ private:
   QString link_type;
 
 
-  char* snlen = nullptr;
-  char* suppresswhite = nullptr;
-  char* urlbase = nullptr;
+  OptionCString snlen;
+  OptionBool suppresswhite;
+  OptionCString urlbase;
   route_head* trk_head{};
   route_head* rte_head{};
   const route_head* current_trk_head{};                // Output.
index 8442a1f96e8f3cb1b609cf9ef630b3bc31cf9bf7..d7a5b7838fc118f45d8e925f74dd64715da76d97 100644 (file)
@@ -79,13 +79,13 @@ GtrnctrFormat::wr_init(const QString& fname)
 
   if (opt_sport) {
     for (unsigned int i = 0; i < std::size(gtc_sportlist); i++) {
-      if (0 == case_ignore_strncmp(opt_sport, gtc_sportlist[i], 2)) {
+      if (0 == case_ignore_strncmp(opt_sport.get(), gtc_sportlist[i], 2)) {
         gtc_sport = i;
         break;
       }
     }
   }
-  gtc_course_flag = xstrtoi(opt_course, nullptr, 10);
+  gtc_course_flag = opt_course;
 }
 
 void
index 1b5b7833fa5987b8f8a3cbc6eaf7005ef6f36c21..1627f1473a377c812cdd8847235e558d226cb471 100644 (file)
--- a/gtrnctr.h
+++ b/gtrnctr.h
@@ -35,6 +35,7 @@
 #include "defs.h"                // for arglist_t, ff_cap, route_head, Waypoint, computed_trkdata, ARG_NOMINMAX, ff_cap_read, ARGTYPE_BOOL, ARGTYPE_STRING, ff_cap_none, ff_cap_write, ff_type, ff_type_file
 #include "format.h"              // for Format
 #include "gbfile.h"              // for gbfile
+#include "option.h"              // for OptionBool, OptionCString
 #include "src/core/datetime.h"   // for DateTime
 #include "xmlgeneric.h"          // for cb_cdata, xg_functor_map_entry, cb_start, cb_end
 
@@ -132,8 +133,8 @@ private:
   double gtc_end_lat{};
   double gtc_end_long{};
 
-  char* opt_sport{};
-  char* opt_course{};
+  OptionCString opt_sport;
+  OptionBool opt_course;
 
   QVector<arglist_t> gtc_args = {
     {
index eb62846f44aa37d7df9babf49bdc08b073a58247..c2694c85dc25fd44ca130891ee0198d39432b997 100644 (file)
--- a/height.cc
+++ b/height.cc
@@ -88,7 +88,7 @@ void HeightFilter::correct_height(const Waypoint* wpt)
       waypointp->altitude += addf;
     }
 
-    if (wgs84tomslopt != nullptr) {
+    if (wgs84tomslopt) {
       waypointp->altitude -= wgs84_separation(waypointp->latitude, waypointp->longitude);
     }
   }
index b59ffe94cc7864c0769dce6885d71cad603c52e5..e39044fad94f7bbb24494e56841be79df05cc1d2 100644 (file)
--- a/height.h
+++ b/height.h
 #ifndef HEIGHT_H_INCLUDED_
 #define HEIGHT_H_INCLUDED_
 
-#include <cstdint>         // for int8_t in heightgrid.h
+#include <cstdint>   // for int8_t in heightgrid.h
 
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
-#include "defs.h"          // for arglist_t, ARG_NOMINMAX, ARGTYPE_BEGIN_REQ, ARGTYPE_BOOL, ARGTYPE_END_REQ, ARGTYPE_FLOAT, Waypoint
-#include "filter.h"        // for Filter
+#include "defs.h"    // for arglist_t, ARG_NOMINMAX, ARGTYPE_BEGIN_REQ, ARGTYPE_BOOL, ARGTYPE_END_REQ, ARGTYPE_FLOAT, Waypoint
+#include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool, OptionCString
 
 #if FILTERS_ENABLED
 
@@ -44,8 +47,8 @@ public:
   void process() override;
 
 private:
-  char* addopt        = nullptr;
-  char* wgs84tomslopt = nullptr;
+  OptionCString addopt;
+  OptionBool wgs84tomslopt;
   double addf{};
   // include static constexpr data member definitions with intializers for grid as private members.
   #include "heightgrid.h"
diff --git a/html.h b/html.h
index 0e930ba2ff7c44649b647ad05a79a9686636debc..a32a6b35a7abc971896ea71b5c11133c4c466981 100644 (file)
--- a/html.h
+++ b/html.h
 #ifndef HTML_H_INCLUDED_
 #define HTML_H_INCLUDED_
 
+#include <QList>                  // for QList
 #include <QString>                // for QString
 #include <QVector>                // for QVector
 
 #include "defs.h"
 #include "format.h"               // for Format
 #include "mkshort.h"              // for MakeShort
+#include "option.h"               // for OptionCString, OptionBool
 #include "src/core/textstream.h"  // for TextStream
 
 
@@ -67,11 +69,11 @@ private:
 
   int waypoint_number{};
 
-  char* stylesheet = nullptr;
-  char* html_encrypt = nullptr;
-  char* includelogs = nullptr;
-  char* degformat = nullptr;
-  char* altunits = nullptr;
+  OptionCString stylesheet;
+  OptionBool html_encrypt;
+  OptionBool includelogs;
+  OptionCString degformat;
+  OptionCString altunits;
 
   QVector<arglist_t> html_args = {
     {
diff --git a/igc.cc b/igc.cc
index 1b831a043a41f1561f409f38297db01cff6a3bc4..49595d03e4c6304ffba1fbae000f065bbde3c4d7 100644 (file)
--- a/igc.cc
+++ b/igc.cc
@@ -478,7 +478,7 @@ void IgcFormat::read()
         igc_ext_type_t ext = get_ext_type(ext_type);
         if (ext != igc_ext_type_t::ext_rec_unknown) {
           supported_extensions.append(name);
-          bool enabled = **ext_option_map.value(ext) == '1';
+          bool enabled = *ext_option_map.value(ext);
           if (enabled) {
             int factor = get_ext_factor(ext);
             ext_types_list.append(std::make_tuple(name, ext, begin, len, factor));
@@ -950,7 +950,7 @@ void IgcFormat::wr_track()
       if (strcmp(timeadj, "auto") == 0) {
         time_adj = correlate_tracks(pres_track, gnss_track);
       } else if (sscanf(timeadj, "%d", &time_adj) != 1) {
-        fatal(MYNAME ": bad timeadj argument '%s'\n", timeadj);
+        fatal(MYNAME ": bad timeadj argument '%s'\n", qPrintable(timeadj.get()));
       }
     } else {
       time_adj = 0;
diff --git a/igc.h b/igc.h
index ba291d167239448263daba2a331d2c64456b34d5..f7ff4fe527445bf5ae0b00988ae05f8c8b62867d 100644 (file)
--- a/igc.h
+++ b/igc.h
 #ifndef IGC_H_INCLUDED_
 #define IGC_H_INCLUDED_
 
-#include <optional>              // for optional
-#include <QByteArray>            // for QByteArray
-#include <QDateTime>             // for QDateTime
-#include <QList>                 // for QList<>::const_iterator
-#include <QString>               // for QString, operator+, QStringLiteral
-#include <QVector>               // for QVector
-#include <QHash>                 // for QHash
+#include <optional>             // for optional
+
+#include <QByteArray>           // for QByteArray
+#include <QDateTime>            // for QDateTime
+#include <QList>                // for QList<>::const_iterator
+#include <QString>              // for QString, operator+, QStringLiteral
+#include <QVector>              // for QVector
+#include <QHash>                // for QHash
 
 #include "defs.h"
-#include "format.h"              // for Format
-#include "formspec.h"            // for FormatSpecificData, kFsIGC
-#include "gbfile.h"              // for gbfprintf, gbfclose, gbfopen, gbfputs, gbfgetstr, gbfile
-#include "src/core/datetime.h"   // for DateTime
-#include "kml.h"                 // for wp_field
+#include "format.h"             // for Format
+#include "formspec.h"           // for FormatSpecificData, kFsIGC
+#include "gbfile.h"             // for gbfprintf, gbfclose, gbfopen, gbfputs, gbfgetstr, gbfile
+#include "kml.h"                // for wp_field
+#include "option.h"             // for OptionBool, OptionCString
+#include "src/core/datetime.h"  // for DateTime
 
 /*
  * Notes on IGC extensions:
@@ -138,18 +140,18 @@ private:
     rec_bad = 1,               // Bad record
   };
 
-  char* opt_enl{nullptr};
-  char* opt_tas{nullptr};
-  char* opt_vat{nullptr};
-  char* opt_oat{nullptr};
-  char* opt_trt{nullptr};
-  char* opt_gsp{nullptr};
-  char* opt_fxa{nullptr};
-  char* opt_siu{nullptr};
-  char* opt_acz{nullptr};
-  char* opt_gfo{nullptr};
-
-  const QHash<igc_ext_type_t, char**> ext_option_map = {
+  OptionBool opt_enl;
+  OptionBool opt_tas;
+  OptionBool opt_vat;
+  OptionBool opt_oat;
+  OptionBool opt_trt;
+  OptionBool opt_gsp;
+  OptionBool opt_fxa;
+  OptionBool opt_siu;
+  OptionBool opt_acz;
+  OptionBool opt_gfo;
+
+  const QHash<igc_ext_type_t, OptionBool*> ext_option_map = {
     {igc_ext_type_t::ext_rec_enl, &opt_enl},
     {igc_ext_type_t::ext_rec_tas, &opt_tas},
     {igc_ext_type_t::ext_rec_vat, &opt_vat},
@@ -292,7 +294,7 @@ private:
   gbfile* file_out{};
   char manufacturer[4] {};
   const route_head* head{};
-  char* timeadj = nullptr;
+  OptionCString timeadj;
 
   QVector<arglist_t> igc_args = {
     {
index 4a88ac0ba636edbbb1f3ea3947729604919d34ad..6de250a8e049ca23ae779ee9fd3c57f9cc5d8a47 100644 (file)
 
 void InterpolateFilter::process()
 {
-  if (((opt_route != nullptr) && (route_count() == 0)) || ((opt_route == nullptr) && (track_count() == 0))) {
+  if ((opt_route && (route_count() == 0)) || (!opt_route && (track_count() == 0))) {
     fatal(FatalMsg() << MYNAME ": Found no routes or tracks to operate on.");
   }
 
   auto process_rte_lambda = [this](const route_head* rte)->void {
     process_rte(const_cast<route_head*>(rte));
   };
-  if (opt_route != nullptr) {
+  if (opt_route) {
     route_disp_all(process_rte_lambda, nullptr, nullptr);
   } else {
     track_disp_all(process_rte_lambda, nullptr, nullptr);
@@ -58,7 +58,7 @@ void InterpolateFilter::process_rte(route_head* rte)
 {
   // Steal all the wpts
   WaypointList wptlist;
-  if (opt_route != nullptr) {
+  if (opt_route) {
     route_swap_wpts(rte, wptlist);
   } else {
     track_swap_wpts(rte, wptlist);
@@ -121,14 +121,14 @@ void InterpolateFilter::process_rte(route_head* rte)
         } else {
           wpt_new->altitude = unknown_alt;
         }
-        if (opt_route != nullptr) {
+        if (opt_route) {
           route_add_wpt(rte, wpt_new);
         } else {
           track_add_wpt(rte, wpt_new);
         }
       }
     }
-    if (opt_route != nullptr) {
+    if (opt_route) {
       route_add_wpt(rte, wpt);
     } else {
       track_add_wpt(rte, wpt);
@@ -145,7 +145,7 @@ void InterpolateFilter::init()
   char* fm;
   if ((opt_time != nullptr) && (opt_dist != nullptr)) {
     fatal(FatalMsg() << MYNAME ": Can't interpolate on both time and distance.");
-  } else if ((opt_time != nullptr) && (opt_route != nullptr)) {
+  } else if ((opt_time != nullptr) && opt_route) {
     fatal(FatalMsg() << MYNAME ": Can't interpolate routes on time.");
   } else if (opt_time != nullptr) {
     max_time_step = 1000 * strtod(opt_time, nullptr); // milliseconds
index 9f09ac5eef1573adbeddd0d04b94e6cf7428f240..79a8d7a187dfb53d90b12066be7b68017aaed742 100644 (file)
 #ifndef INTERPOLATE_H_INCLUDED_
 #define INTERPOLATE_H_INCLUDED_
 
-#include <QString>              // for QString
-#include <QVector>              // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
-#include "defs.h"               // for ARG_NOMINMAX, arglist_t, ARGTYPE_BEGIN_EXCL, ARG...
-#include "filter.h"             // for Filter
+#include "defs.h"    // for ARG_NOMINMAX, arglist_t, ARGTYPE_BEGIN_EXCL, ARG...
+#include "filter.h"  // for Filter
+#include "option.h"  // for OptionCString, OptionBool
 
 #if FILTERS_ENABLED
 
@@ -47,11 +49,11 @@ private:
 
   /* Data Members */
 
-  char* opt_time{nullptr};
+  OptionCString opt_time;
   double max_time_step{0};
-  char* opt_dist{nullptr};
+  OptionCString opt_dist;
   double max_dist_step{0};
-  char* opt_route{nullptr};
+  OptionBool opt_route;
 
   QVector<arglist_t> args = {
     {
diff --git a/kml.cc b/kml.cc
index 684fb481dc9329b20c5bcbb41a4bd336fc3a7174..9d529e108e48daca0f9d2fa7e3567f9c435ff987 100644 (file)
--- a/kml.cc
+++ b/kml.cc
@@ -413,7 +413,7 @@ void KmlFormat::wr_init(const QString& fname)
     unitsformatter->setunits(UnitsFormatter::units_t::aviation);
     break;
   default:
-    fatal("Units argument '%s' should be 's' for statute units, 'm' for metric, 'n' for nautical or 'a' for aviation.\n", opt_units);
+    fatal("Units argument '%s' should be 's' for statute units, 'm' for metric, 'n' for nautical or 'a' for aviation.\n", qPrintable(opt_units.get()));
     break;
   }
   /*
@@ -472,11 +472,11 @@ void KmlFormat::wr_position_deinit()
 }
 
 
-void KmlFormat::kml_output_linestyle(char* /*color*/, int width) const
+void KmlFormat::kml_output_linestyle(const QString& color, int width) const
 {
   // Style settings for line strings
   writer->writeStartElement(QStringLiteral("LineStyle"));
-  writer->writeTextElement(QStringLiteral("color"), opt_line_color);
+  writer->writeTextElement(QStringLiteral("color"), color);
   writer->writeTextElement(QStringLiteral("width"), QString::number(width));
   writer->writeEndElement(); // Close LineStyle tag
 }
@@ -516,7 +516,7 @@ void KmlFormat::kml_write_bitmap_style_(const QString& style, const QString& bit
   }
 
   if (is_multitrack) {
-    kml_output_linestyle(opt_line_color,
+    kml_output_linestyle(opt_line_color.get(),
                          highlighted ? line_width + 2 :
                          line_width);
   }
@@ -872,7 +872,7 @@ void KmlFormat::kml_output_point(const Waypoint* waypointp, kml_point_type pt_ty
 
   if (export_points) {
     writer->writeStartElement(QStringLiteral("Placemark"));
-    if (xstrtoi(opt_labels, nullptr, 10)) {
+    if (opt_labels) {
       writer->writeOptionalTextElement(QStringLiteral("name"), waypointp->shortname);
     }
     writer->writeEmptyElement(QStringLiteral("snippet"));
@@ -885,7 +885,7 @@ void KmlFormat::kml_output_point(const Waypoint* waypointp, kml_point_type pt_ty
       writer->writeStartElement(QStringLiteral("Style"));
       writer->writeStartElement(QStringLiteral("IconStyle"));
       writer->writeStartElement(QStringLiteral("Icon"));
-      writer->writeTextElement(QStringLiteral("href"), opt_deficon);
+      writer->writeTextElement(QStringLiteral("href"), opt_deficon.get());
       writer->writeEndElement(); // Close Icon tag
       writer->writeEndElement(); // Close IconStyle tag
       writer->writeEndElement(); // Close Style tag
@@ -944,7 +944,7 @@ void KmlFormat::kml_output_tailer(const route_head* header)
         kml_step_color();
         writer->writeTextElement(QStringLiteral("color"), QStringLiteral("%1%2")
                                  .arg(kml_color_sequencer.color.opacity, 2, 16, QChar('0')).arg(kml_color_sequencer.color.bbggrr, 6, 16, QChar('0')));
-        writer->writeTextElement(QStringLiteral("width"), opt_line_width);
+        writer->writeTextElement(QStringLiteral("width"), opt_line_width.get());
       } else {
         if (header->line_color.bbggrr >= 0) {
           writer->writeTextElement(QStringLiteral("color"), QStringLiteral("%1%2")
@@ -1455,7 +1455,7 @@ void KmlFormat::kml_waypt_pr(const Waypoint* waypointp) const
   kml_output_timestamp(waypointp);
 
   // Icon - but only if it looks like a URL.
-  icon = opt_deficon ? opt_deficon : waypointp->icon_descr;
+  icon = opt_deficon ? opt_deficon.get() : waypointp->icon_descr;
   if (icon.contains("://")) {
     writer->writeStartElement(QStringLiteral("Style"));
     writer->writeStartElement(QStringLiteral("IconStyle"));
@@ -1844,14 +1844,14 @@ void KmlFormat::kml_mt_array_schema(const QString& field_name, const QString& di
 void KmlFormat::write()
 {
   // Parse options
-  export_lines = (0 == strcmp("1", opt_export_lines));
-  export_points = (0 == strcmp("1", opt_export_points));
-  export_track = (0 ==  strcmp("1", opt_export_track));
-  floating = (!! strcmp("0", opt_floating));
-  extrude = (!! strcmp("0", opt_extrude));
+  export_lines = opt_export_lines;
+  export_points = opt_export_points;
+  export_track = opt_export_track;
+  floating = opt_floating;
+  extrude = opt_extrude;
   rotate_colors = (!! opt_rotate_colors);
-  trackdata = (!! strcmp("0", opt_trackdata));
-  trackdirection = (!! strcmp("0", opt_trackdirection));
+  trackdata = opt_trackdata;
+  trackdirection = opt_trackdirection;
   line_width = xstrtoi(opt_line_width, nullptr, 10);
   precision = xstrtoi(opt_precision, nullptr, 10);
 
@@ -1902,7 +1902,7 @@ void KmlFormat::write()
   if (track_waypt_count() || route_waypt_count()) {
     writer->writeStartElement(QStringLiteral("Style"));
     writer->writeAttribute(QStringLiteral("id"), QStringLiteral("lineStyle"));
-    kml_output_linestyle(opt_line_color, line_width);
+    kml_output_linestyle(opt_line_color.get(), line_width);
     writer->writeEndElement(); // Close Style tag
   }
 
diff --git a/kml.h b/kml.h
index e225ece41995ac7958ce59dba83d5224d2dcbe4b..2454101d6cf0381768203dd8e9d8b7115463d1f1 100644 (file)
--- a/kml.h
+++ b/kml.h
@@ -34,6 +34,7 @@
 
 #include "defs.h"
 #include "format.h"
+#include "option.h"                    // for OptionBool, OptionCString
 #include "src/core/datetime.h"         // for DateTime
 #include "src/core/file.h"             // for File
 #include "src/core/xmlstreamwriter.h"  // for XmlStreamWriter
@@ -138,7 +139,7 @@ private:
   void gx_trk_e(const QString& args, const QXmlStreamAttributes* attrs);
   void gx_trk_when(const QString& args, const QXmlStreamAttributes* attrs);
   void gx_trk_coord(const QString& args, const QXmlStreamAttributes* attrs);
-  void kml_output_linestyle(char* color, int width) const;
+  void kml_output_linestyle(const QString& color, int width) const;
   void kml_write_bitmap_style_(const QString& style, const QString& bitmap, bool highlighted, bool force_heading) const;
   void kml_write_bitmap_style(kml_point_type pt_type, const QString& bitmap, const QString& customstyle) const;
   void kml_output_timestamp(const Waypoint* waypointp) const;
@@ -193,21 +194,21 @@ private:
   QHash<const route_head*, track_trait_t> kml_track_traits_hash;
 
   // options
-  char* opt_deficon{nullptr};
-  char* opt_export_lines{nullptr};
-  char* opt_export_points{nullptr};
-  char* opt_export_track{nullptr};
-  char* opt_line_width{nullptr};
-  char* opt_line_color{nullptr};
-  char* opt_floating{nullptr};
-  char* opt_extrude{nullptr};
-  char* opt_trackdata{nullptr};
-  char* opt_trackdirection{nullptr};
-  char* opt_units{nullptr};
-  char* opt_labels{nullptr};
-  char* opt_max_position_points{nullptr};
-  char* opt_rotate_colors{nullptr};
-  char* opt_precision{nullptr};
+  OptionCString opt_deficon;
+  OptionBool opt_export_lines;
+  OptionBool opt_export_points;
+  OptionBool opt_export_track;
+  OptionCString opt_line_width;
+  OptionCString opt_line_color;
+  OptionBool opt_floating;
+  OptionBool opt_extrude;
+  OptionBool opt_trackdata;
+  OptionBool opt_trackdirection;
+  OptionCString opt_units;
+  OptionBool opt_labels;
+  OptionCString opt_max_position_points;
+  OptionCString opt_rotate_colors;
+  OptionCString opt_precision;
 
   bool export_lines{};
   bool export_points{};
index 9e12d39313717c77c096cb0732a8af005eb3308a..00586f46074910c9e19703fdb5e7e48ad5c084cd 100644 (file)
@@ -348,7 +348,7 @@ LowranceusrFormat::wr_init(const QString& fname)
   waypt_out_count = 0;
   writing_version = xstrtoi(opt_wversion, nullptr, 10);
   if ((writing_version < 2) || (writing_version > 4)) {
-    fatal(MYNAME " wversion value %s is not supported !!\n", opt_wversion);
+    fatal(MYNAME " wversion value %s is not supported !!\n", qPrintable(opt_wversion.get()));
   }
   utf16le_codec = QTextCodec::codecForName("UTF-16LE");
   waypt_table = new QList<const Waypoint*>;
@@ -917,7 +917,7 @@ LowranceusrFormat::lowranceusr_parse_icons() const
     double longitude   = lon_mm_to_deg(gbfgetint32(file_in));
     int    icon_number = gbfgetint32(file_in);
 
-    if (opt_ignoreicons == nullptr) {          /* Option not specified if NULL */
+    if (!opt_ignoreicons) {
       auto* wpt_tmp = new Waypoint;
 
       /* position coord lat & long */
@@ -1886,7 +1886,9 @@ LowranceusrFormat::write()
       buf = QString("GPSBabel generated USR data file");
     } else {
       if (len > MAXUSRSTRINGSIZE) {
-        opt_title[MAXUSRSTRINGSIZE] = '\000';  // truncate it before copy
+        QString title = opt_title.get();
+        title.truncate(MAXUSRSTRINGSIZE);
+        opt_title.set(title); // truncate it before copy
       }
       buf = opt_title;
     }
@@ -1916,7 +1918,9 @@ LowranceusrFormat::write()
       buf = QString("Waypoints, routes, and trails");
     } else {
       if (len > MAXUSRSTRINGSIZE) {
-        opt_content_descr[MAXUSRSTRINGSIZE] = '\000';  // truncate it before copy
+        QString content_descr = opt_content_descr.get();
+        content_descr.truncate(MAXUSRSTRINGSIZE);
+        opt_content_descr.set(content_descr); // truncate it before copy
       }
       buf = opt_content_descr;
     }
index ee54fc46d182faa6138deb5c48445e1f8903c15e..ae990f9061612b9527cda2ca6cf489e53cdbe2b3 100644 (file)
 
 #include "defs.h"
 #include "format.h"
-#include "formspec.h"             // for FsChainFind, FsChainAdd, kFsLowranceusr4, FormatSpecificData
-#include "gbfile.h"               // for gbfgetint32, gbfputint32, gbfputint16, gbfgetc, gbfgetint16, gbfwrite, gbfputc, gbfeof, gbfgetflt, gbfclose, gbfgetdbl, gbfopen_le, gbfputdbl, gbfputs, gbfile, gbfputflt, gbfread, gbfseek
-#include "mkshort.h"              // for MakeShort
-#include "src/core/datetime.h"    // for DateTime
+#include "formspec.h"           // for FsChainFind, FsChainAdd, kFsLowranceusr4, FormatSpecificData
+#include "gbfile.h"             // for gbfgetint32, gbfputint32, gbfputint16, gbfgetc, gbfgetint16, gbfwrite, gbfputc, gbfeof, gbfgetflt, gbfclose, gbfgetdbl, gbfopen_le, gbfputdbl, gbfputs, gbfile, gbfputflt, gbfread, gbfseek
+#include "mkshort.h"            // for MakeShort
+#include "option.h"             // for OptionBool, OptionCString
+#include "src/core/datetime.h"  // for DateTime
 
 
 class LowranceusrFormat : public Format
@@ -444,13 +445,13 @@ private:
   int            route_uid{};
   int            trail_uid{};
 
-  char*          opt_ignoreicons{};
-  char*          opt_writeasicons{};
-  char*          opt_seg_break{};
-  char*          opt_wversion{};
-  char*          opt_title{};
-  char*          opt_content_descr{};
-  char*          opt_serialnum{};
+  OptionBool  opt_ignoreicons;
+  OptionBool  opt_writeasicons;
+  OptionBool  opt_seg_break;
+  OptionCString  opt_wversion;
+  OptionCString  opt_title;
+  OptionCString  opt_content_descr;
+  OptionCString  opt_serialnum;
   int            opt_serialnum_i{};
 
   QList<const Waypoint*>* waypt_table{nullptr};
@@ -460,7 +461,7 @@ private:
   int            trail_point_count{};
   bool           merge_new_track{false};
   short          num_section_points{};
-  char*          merge{};
+  OptionBool  merge;
   int            reading_version{};
   int            rstream_version{};
   int            writing_version{};
index 3a2217c8503e26b398dd447f0fe98dfa6fc5d1a5..fa9e3e7f9c43b43077eeea596b484376a9d49f40 100644 (file)
@@ -354,7 +354,7 @@ void MtkLoggerBase::mtk_read()
   char* fusage = nullptr;
 
 
-  if (*OPT_erase_only != '0') {
+  if (OPT_erase_only) {
     mtk_erase();
     return;
   }
@@ -587,7 +587,7 @@ mtk_retry:
   }
 
   // Fixme - Order or. Enable - parse - erase ??
-  if (log_enabled || *OPT_log_enable=='1') {
+  if (log_enabled || OPT_log_enable) {
     i = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", nullptr, 2);
     dbg(3, " ---- LOG ENABLE ----%s\n", i==0?"Success":"Fail");
   } else {
@@ -605,7 +605,7 @@ mtk_retry:
   file_deinit();
 
   /* fixme -- we're assuming all went well - erase flash.... */
-  if (*OPT_erase != '0') {
+  if (OPT_erase) {
     mtk_erase();
   }
 
@@ -733,7 +733,7 @@ int MtkLoggerBase::add_trackpoint(int idx, unsigned long bmask, data_item* itm)
 
 
 /********************** MTK Logger -- CSV output *************************/
-void MtkLoggerBase::mtk_csv_init(char* csv_fname, unsigned long bitmask)
+void MtkLoggerBase::mtk_csv_init(const char* csv_fname, unsigned long bitmask)
 {
   FILE* cf;
 
@@ -1397,7 +1397,7 @@ void MtkLoggerBase::file_read()
   mtk_info.logLen = mtk_log_len(mtk_info.bitmask);
   dbg(3, "Log item size %d bytes\n", mtk_info.logLen);
   if (csv_file && *csv_file) {
-    mtk_csv_init(csv_file, mtk_info.bitmask);
+    mtk_csv_init(static_cast<const char*>(csv_file), mtk_info.bitmask);
   }
 
   while (pos < fsize && (bLen = fread(&buf[j], 1, sizeof(buf)-j, fl)) > 0) {
index 7b8b7602ea546e69d1a9abd9a96eabe5c69fd7c2..1059943c2943f0c3e10682a6daa62baa3b566bcf 100644 (file)
@@ -63,6 +63,7 @@
 #include "defs.h"
 #include "format.h"  // for Format
 #include "gbfile.h"  // for gbfile
+#include "option.h"  // for OptionBool, OptionCString
 
 
 class MtkLoggerBase
@@ -216,11 +217,11 @@ protected:
   void* fd{};  /* serial fd */
   FILE* fl{};  /* bin.file fd */
   char* port{}; /* serial port name */
-  char* OPT_erase{};  /* erase ? command option */
-  char* OPT_erase_only{};  /* erase_only ? command option */
-  char* OPT_log_enable{};  /* enable ? command option */
-  char* csv_file{}; /* csv ? command option */
-  char* OPT_block_size_kb{}; /* block_size_kb ? command option */
+  OptionBool OPT_erase;  /* erase ? command option */
+  OptionBool OPT_erase_only;  /* erase_only ? command option */
+  OptionBool OPT_log_enable;  /* enable ? command option */
+  OptionCString csv_file; /* csv ? command option */
+  OptionCString OPT_block_size_kb; /* block_size_kb ? command option */
   MTK_DEVICE_TYPE mtk_device = MTK_LOGGER;
 
   mtk_loginfo mtk_info{};
@@ -279,7 +280,7 @@ protected:
   int mtk_erase();
   void mtk_read();
   int add_trackpoint(int idx, long unsigned int bmask, data_item* itm);
-  void mtk_csv_init(char* csv_fname, long unsigned int bitmask);
+  void mtk_csv_init(const char* csv_fname, long unsigned int bitmask);
   void mtk_csv_deinit();
   static int csv_line(gbfile* csvFile, int idx, long unsigned int bmask, data_item* itm);
   int mtk_parse(unsigned char* data, int dataLen, unsigned int bmask);
diff --git a/nmea.cc b/nmea.cc
index 62f9062424b0da7f5dc8a476c65074f1495629ae..91d1899c902206b6044587e4556fd9fc14f0f8e9 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -157,7 +157,6 @@ sentence is truncated - and missing part of the line, including the checksum.
 */
 
 #define MYNAME "nmea"
-#define CHECK_BOOL(a) if ((a) && (*(a) == '0')) (a) = NULL
 
 /*
  * Slightly different than the Magellan checksum fn.
@@ -226,12 +225,6 @@ NmeaFormat::rd_init(const QString& fname)
   datum = kDatumWGS84;
   had_checksum = false;
 
-  CHECK_BOOL(opt_gprmc);
-  CHECK_BOOL(opt_gpgga);
-  CHECK_BOOL(opt_gpvtg);
-  CHECK_BOOL(opt_gpgsa);
-  CHECK_BOOL(opt_gisteq);
-
   pcmpt_head.clear();
 
   if (getposnarg) {
@@ -283,15 +276,7 @@ NmeaFormat::rd_deinit()
 void
 NmeaFormat::wr_init(const QString& fname)
 {
-  CHECK_BOOL(opt_gprmc);
-  CHECK_BOOL(opt_gpgga);
-  CHECK_BOOL(opt_gpvtg);
-  CHECK_BOOL(opt_gpgsa);
-  CHECK_BOOL(opt_gisteq);
-
-  append_output = strtod(opt_append, nullptr);
-
-  file_out = gbfopen(fname, append_output ? "a+" : "w+", MYNAME);
+  file_out = gbfopen(fname, opt_append ? "a+" : "w+", MYNAME);
 
   sleepms = -1;
   if (opt_sleep) {
@@ -306,9 +291,9 @@ NmeaFormat::wr_init(const QString& fname)
   mkshort_handle->set_length(xstrtoi(snlenopt, nullptr, 10));
 
   if (opt_gisteq) {
-    opt_gpgga = nullptr;
-    opt_gpvtg = nullptr;
-    opt_gpgsa = nullptr;
+    opt_gpgga.reset();
+    opt_gpvtg.reset();
+    opt_gpgsa.reset();
   }
 }
 
@@ -460,7 +445,6 @@ NmeaFormat::gpgga_parse(const QString& ibuf)
    * as serial units will often spit a remembered position up and
    * that is more comfortable than nothing at all...
    */
-  CHECK_BOOL(opt_ignorefix);
   if ((fix <= 0) && (read_mode != rm_serial || (latdeg == 0.0 && lngdeg == 0.0)) && (!opt_ignorefix)) {
     return;
   }
@@ -997,9 +981,9 @@ NmeaFormat::read()
   }
 
   if (optdate) {
-    opt_tm = QDate::fromString(optdate, u"yyyyMMdd");
+    opt_tm = QDate::fromString(optdate.get(), u"yyyyMMdd");
     if (!opt_tm.isValid()) {
-      fatal(MYNAME ": Invalid date \"%s\"!\n", optdate);
+      fatal(MYNAME ": Invalid date \"%s\"!\n", qPrintable(optdate.get()));
     }
   }
 
@@ -1062,7 +1046,7 @@ NmeaFormat::rd_position_init(const QString& fname)
 
   if (opt_baud) {
     if (!gbser_set_speed(gbser_handle, xstrtoi(opt_baud, nullptr, 10))) {
-      fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud);
+      fatal(MYNAME ": Unable to set baud rate %s\n", qPrintable(opt_baud.get()));
     }
   }
   posn_fname = fname;
diff --git a/nmea.h b/nmea.h
index e265f051b40045409ca099f27295dd5779c8fce2..9f5ca4f4c3d176e3e6a63b8162227cf9f0b0edc9 100644 (file)
--- a/nmea.h
+++ b/nmea.h
 #ifndef NMEA_H_INCLUDED_
 #define NMEA_H_INCLUDED_
 
-#include <QByteArray>         // for QByteArray
-#include <QDate>              // for QDate
-#include <QDateTime>          // for QDateTime
-#include <QList>              // for QList
-#include <QString>            // for QString
-#include <QTime>              // for QTime
-#include <QVector>            // for QVector
+#include <QByteArray>  // for QByteArray
+#include <QDate>       // for QDate
+#include <QDateTime>   // for QDateTime
+#include <QList>       // for QList
+#include <QString>     // for QString
+#include <QTime>       // for QTime
+#include <QVector>     // for QVector
 
 #include "defs.h"
-#include "format.h"           // for Format
-#include "gbfile.h"           // for gbfile
-#include "mkshort.h"          // for MakeShort
+#include "format.h"    // for Format
+#include "gbfile.h"    // for gbfile
+#include "mkshort.h"   // for MakeShort
+#include "option.h"    // for OptionBool, OptionCString
 
 
 class NmeaFormat : public Format
@@ -135,22 +136,21 @@ private:
   int without_date{};  /* number of created trackpoints without a valid date */
   QDate opt_tm;        /* converted "date" parameter */
 
-  char* opt_gprmc{};
-  char* opt_gpgga{};
-  char* opt_gpvtg{};
-  char* opt_gpgsa{};
-  char* snlenopt{};
-  char* optdate{};
-  char* getposnarg{};
-  char* opt_sleep{};
-  char* opt_baud{};
-  char* opt_append{};
-  char* opt_gisteq{};
-  char* opt_ignorefix{};
+  OptionBool opt_gprmc;
+  OptionBool opt_gpgga;
+  OptionBool opt_gpvtg;
+  OptionBool opt_gpgsa;
+  OptionCString snlenopt;
+  OptionCString optdate;
+  OptionBool getposnarg;
+  OptionCString opt_sleep;
+  OptionCString opt_baud;
+  OptionBool opt_append;
+  OptionBool opt_gisteq;
+  OptionBool opt_ignorefix;
 
   long sleepms{};
   int getposn{};
-  int append_output{};
   bool amod_waypoint{};
 
   QDateTime last_write_time;
index 0b30e9a8e2cb58846429fbfcac6b7699573c1c8b..e2598523d7846b48a688b39babe3eb44d52fefc7 100644 (file)
 
 void NukeDataFilter::process()
 {
-  if (*nukewpts != '0') {
+  if (nukewpts) {
     waypt_flush_all();
   }
-  if (*nuketrks != '0') {
+  if (nuketrks) {
     route_flush_all_tracks();
   }
-  if (*nukertes != '0') {
+  if (nukertes) {
     route_flush_all_routes();
   }
 }
index ec05dd64e562730cc1b6061abe20da40d91b9dc5..0c9b192b576ea320016415ea5ff9cf8c9c45b77f 100644 (file)
 #ifndef NUKEDATA_H_INCLUDED_
 #define NUKEDATA_H_INCLUDED_
 
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
 #include "defs.h"    // for ARGTYPE_BOOL, ARG_NOMINMAX, arglist_t, ARG_TERMI...
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool
 
 #if FILTERS_ENABLED
 
@@ -40,9 +43,9 @@ public:
   void process() override;
 
 private:
-  char* nukewpts{};
-  char* nuketrks{};
-  char* nukertes{};
+  OptionBool nukewpts;
+  OptionBool nuketrks;
+  OptionBool nukertes;
 
   QVector<arglist_t> args = {
     {
diff --git a/option.h b/option.h
new file mode 100644 (file)
index 0000000..12fb46b
--- /dev/null
+++ b/option.h
@@ -0,0 +1,169 @@
+/*
+    Copyright (C) 2024 Robert Lipe, robertlipe+source@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ */
+#ifndef OPTION_H_INCLUDED_
+#define OPTION_H_INCLUDED_
+
+#include <QByteArray>  // for QByteArray
+#include <QString>     // for QString, operator!=
+
+class Option /* Abstract Class */
+{
+public:
+  /* Types */
+  enum option_t {
+    type_cstring,
+    type_boolean,
+  };
+
+  /* Special Member Functions */
+  Option() = default;
+  // Provide virtual public destructor to avoid undefined behavior when
+  // an object of derived class type is deleted through a pointer to
+  // its base class type.
+  // https://wiki.sei.cmu.edu/confluence/display/cplusplus/OOP52-CPP.+Do+not+delete+a+polymorphic+object+without+a+virtual+destructor
+  virtual ~Option() = default;
+  // And that requires us to explicitly default or delete the move and copy operations.
+  // To prevent slicing we delete them.
+  // https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all.
+  Option(const Option&) = delete;
+  Option& operator=(const Option&) = delete;
+  Option(Option&&) = delete;
+  Option& operator=(Option&&) = delete;
+
+  /* Member Functions */
+  [[nodiscard]] virtual option_t type() const = 0;
+  [[nodiscard]] virtual bool has_value() const = 0;
+  virtual void reset() = 0;
+  [[nodiscard]] virtual bool isEmpty() const = 0;
+  [[nodiscard]] virtual const QString& get() const = 0;
+  virtual void set(const QString& s) = 0;
+
+  /* Data Members */
+  // I.25: Prefer empty abstract classes as interfaces to class hierarchies
+  // https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i25-prefer-empty-abstract-classes-as-interfaces-to-class-hierarchies
+};
+
+class OptionCString : public Option
+{
+public:
+  /* Special Member Functions */
+  OptionCString() = default;
+
+  /* Traditionally a nullptr value indicated the option was not supplied.
+   * This was convenient because a char* can be implicitly converted to bool,
+   * although now we also have the equivalent member function has_value().
+   * Because QByteArray::constData() != nullptr for a null QByteArray we
+   * have to handle that case manually.
+   */
+  explicit(false) operator const char* () const
+  {
+    return value_.isNull()? nullptr : valueb_.constData();
+  }
+
+  [[nodiscard]] option_t type() const override
+  {
+    return type_cstring;
+  }
+
+  [[nodiscard]] bool has_value() const override
+  {
+    return !value_.isNull();
+  }
+
+  void reset() override
+  {
+    value_ = QString();
+    valueb_ = QByteArray();
+  }
+
+  [[nodiscard]] bool isEmpty() const override
+  {
+    return value_.isEmpty();
+  }
+
+  [[nodiscard]] const QString& get() const override
+  {
+    return value_;
+  }
+
+  [[nodiscard]] const QByteArray& getba() const
+  {
+    return valueb_;
+  }
+
+  void set(const QString& s) override
+  {
+    value_ = s;
+    valueb_ = s.toUtf8();
+  }
+
+private:
+  QString value_;
+  QByteArray valueb_;
+};
+
+class OptionBool : public Option
+{
+public:
+  /* Special Member Functions */
+  OptionBool() = default;
+
+  /* Traditionally unsupplied bool options without default are considered to be false. */
+  explicit(false) operator bool() const
+  {
+    return (!value_.isNull() && (value_ != '0'));
+  }
+
+  [[nodiscard]] option_t type() const override
+  {
+    return type_boolean;
+  }
+
+  /* Note that has_value can be used to distinguish an option that wasn't supplied
+   * from one that was supplied and is considered false by Vecs::assign_option.
+   */
+  [[nodiscard]] bool has_value() const override
+  {
+    return !value_.isNull();
+  }
+
+  void reset() override
+  {
+    value_ = QString();
+  }
+
+  [[nodiscard]] bool isEmpty() const override
+  {
+    return value_.isEmpty();
+  }
+
+  [[nodiscard]] const QString& get() const override
+  {
+    return value_;
+  }
+
+  void set(const QString& s) override
+  {
+    value_ = s;
+  }
+
+private:
+  QString value_;
+};
+#endif // OPTION_H_INCLUDED_
diff --git a/osm.cc b/osm.cc
index 06670f403d32fc0c1ad92496ec7f3bc2f01d68e0..230da84103d83e3644669ccbf192de9366dc5f16 100644 (file)
--- a/osm.cc
+++ b/osm.cc
@@ -754,7 +754,7 @@ OsmFormat::osm_waypt_disp(const Waypoint* waypoint)
     break;
   }
 
-  if (QString creator = created_by; !creator.isEmpty()) {
+  if (QString creator = created_by.get(); !creator.isEmpty()) {
     if (!gpsbabel_testmode()) {
       if (creator == "GPSBabel") {
         creator += '-';
@@ -770,7 +770,7 @@ OsmFormat::osm_waypt_disp(const Waypoint* waypoint)
     osm_disp_feature(waypoint);
   }
 
-  osm_write_opt_tag(opt_tagnd);
+  osm_write_opt_tag(opt_tagnd.get());
 
   fout->writeEndElement(); // node
 }
@@ -813,7 +813,7 @@ OsmFormat::osm_rte_disp_trail(const route_head* route)
     return;
   }
 
-  if (QString creator = created_by; !creator.isEmpty()) {
+  if (QString creator = created_by.get(); !creator.isEmpty()) {
     if (!gpsbabel_testmode()) {
       if (creator == "GPSBabel") {
         creator += '-';
@@ -826,7 +826,7 @@ OsmFormat::osm_rte_disp_trail(const route_head* route)
   osm_write_tag("name", route->rte_name);
   osm_write_tag("note", route->rte_desc);
 
-  osm_write_opt_tag(opt_tag);
+  osm_write_opt_tag(opt_tag.get());
 
   fout->writeEndElement(); // way
 }
diff --git a/osm.h b/osm.h
index a5591930b78ebfb9cd08de5c86dd030f4452a8dd..b983e2dacfaf7d07ed9eade397aa4ae710765149 100644 (file)
--- a/osm.h
+++ b/osm.h
@@ -32,6 +32,7 @@
 
 #include "defs.h"
 #include "format.h"                    // for Format
+#include "option.h"                    // for OptionCString
 #include "src/core/file.h"             // for File
 #include "src/core/xmlstreamwriter.h"  // for XmlStreamWriter
 #include "xmlgeneric.h"                // for xg_functor_map_entry, cb_start, cb_end
@@ -110,9 +111,9 @@ private:
 
   /* Data Members */
 
-  char* opt_tag{};
-  char* opt_tagnd{};
-  char* created_by{};
+  OptionCString opt_tag;
+  OptionCString opt_tagnd;
+  OptionCString created_by;
 
   QVector<arglist_t> osm_args = {
     { "tag", &opt_tag,         "Write additional way tag key/value pairs", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr},
diff --git a/ozi.cc b/ozi.cc
index 83d343b2b3d1d3e321fa1a7a0bac04f9690f929d..1c156e3e6cd975452722ff3e08ff27ec9bb0c0e7 100644 (file)
--- a/ozi.cc
+++ b/ozi.cc
@@ -332,7 +332,7 @@ OziFormat::ozi_init_units(const int direction)      /* 0 = in; 1 = out */
     alt_scale = FEET_TO_METERS(1.0);
     break;
   default:
-    fatal(MYNAME ": Unknown value (%s) for option 'altunit'!\n", altunit_opt);
+    fatal(MYNAME ": Unknown value (%s) for option 'altunit'!\n", qPrintable(altunit_opt.get()));
   }
   if (direction != 0) {
     alt_scale = 1 / alt_scale;
@@ -350,7 +350,7 @@ OziFormat::ozi_init_units(const int direction)      /* 0 = in; 1 = out */
     prox_scale = 1000.0;
     break;
   default:
-    fatal(MYNAME ": Unknown value (%s) for option 'proxunit'!\n", proxunit_opt);
+    fatal(MYNAME ": Unknown value (%s) for option 'proxunit'!\n", qPrintable(proxunit_opt.get()));
   }
   if (direction != 0) {
     prox_scale = 1 / prox_scale;
@@ -389,16 +389,16 @@ OziFormat::wr_init(const QString& fname)
 
     mkshort_handle->set_length(xstrtoi(snlenopt, nullptr, 10));
 
-    if (snwhiteopt) {
-      mkshort_handle->set_whitespace_ok(xstrtoi(snwhiteopt, nullptr, 10));
+    if (snwhiteopt.has_value()) {
+      mkshort_handle->set_whitespace_ok(snwhiteopt);
     }
 
-    if (snupperopt) {
-      mkshort_handle->set_mustupper(xstrtoi(snupperopt, nullptr, 10));
+    if (snupperopt.has_value()) {
+      mkshort_handle->set_mustupper(snupperopt);
     }
 
-    if (snuniqueopt) {
-      mkshort_handle->set_mustuniq(xstrtoi(snuniqueopt, nullptr, 10));
+    if (snuniqueopt.has_value()) {
+      mkshort_handle->set_mustuniq(snuniqueopt);
     }
 
     mkshort_handle->set_badchars("\",");
diff --git a/ozi.h b/ozi.h
index fc4478a4768af6abfdcd8a34e9aee01cc30ceb81..78cf9a606ea364af14030bc8689391899d328d48 100644 (file)
--- a/ozi.h
+++ b/ozi.h
@@ -38,6 +38,7 @@
 #ifndef OZI_H_INCLUDED_
 #define OZI_H_INCLUDED_
 
+#include <QList>                  // for QList
 #include <QIODevice>              // for QIODeviceBase, QIODeviceBase::OpenModeFlag
 #include <QString>                // for QString
 #include <QVector>                // for QVector
@@ -46,6 +47,7 @@
 #include "format.h"               // for Format
 #include "formspec.h"             // for FormatSpecificData, kFsOzi
 #include "mkshort.h"              // for MakeShort
+#include "option.h"               // for OptionCString, OptionBool
 #include "src/core/textstream.h"  // for TextStream
 
 
@@ -124,23 +126,23 @@ private:
   int route_wpt_count{};
   int new_track{};
 
-  char* snlenopt = nullptr;
-  char* snwhiteopt = nullptr;
-  char* snupperopt = nullptr;
-  char* snuniqueopt = nullptr;
-  char* wptfgcolor = nullptr;
-  char* wptbgcolor = nullptr;
-  char* pack_opt = nullptr;
+  OptionCString snlenopt;
+  OptionBool snwhiteopt;
+  OptionBool snupperopt;
+  OptionBool snuniqueopt;
+  OptionCString wptfgcolor;
+  OptionCString wptbgcolor;
+  OptionBool pack_opt;
   int datum{};
-  char* proximityarg = nullptr;
+  OptionCString proximityarg;
   double proximity{};
-  char* altunit_opt{};
-  char* proxunit_opt{};
+  OptionCString altunit_opt;
+  OptionCString proxunit_opt;
   char altunit{};
   char proxunit{};
   double alt_scale{};
   double prox_scale{};
-  char* opt_codec{};
+  OptionCString opt_codec;
 
   QVector<arglist_t> ozi_args = {
     {
index 7f988ebdb128635abe62bea6b3dbeb1e8b5487c7..7ca2210649c22cc3e4ef9e53b00567d8e28120bc 100644 (file)
@@ -229,7 +229,7 @@ void PolygonFilter::process()
   QString line;
 
   gpsbabel::TextStream stream;
-  stream.open(polyfileopt, QIODevice::ReadOnly, MYNAME);
+  stream.open(polyfileopt.get(), QIODevice::ReadOnly, MYNAME);
 
   double olat = BADVAL;
   double olon = BADVAL;
@@ -305,7 +305,7 @@ void PolygonFilter::process()
       if (ed->override) {
         ed->state = INSIDE;
       }
-      if (((ed->state & INSIDE) == OUTSIDE) == (exclopt == nullptr)) {
+      if (((ed->state & INSIDE) == OUTSIDE) == !exclopt) {
         wp->wpt_flags.marked_for_deletion = 1;
       }
       delete ed;
index 4c6d1d179c9e1a6317c089dbfeef3b03262ea434..40915eb049e5b0a2208a8a5c26373e7888fb063f 100644 (file)
--- a/polygon.h
+++ b/polygon.h
 #ifndef POLYGON_H_INCLUDED_
 #define POLYGON_H_INCLUDED_
 
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
 #include "defs.h"    // for ARG_NOMINMAX, arglist_t, ARGTYPE_BOOL, ARGTYPE_FILE
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool, OptionCString
 
 #if FILTERS_ENABLED
 
@@ -55,8 +58,8 @@ private:
 
   /* Data Members */
 
-  char* polyfileopt = nullptr;
-  char* exclopt = nullptr;
+  OptionCString polyfileopt;
+  OptionBool exclopt;
 
   QVector<arglist_t> args = {
     {
index 759e9e11ff859f7f804b0748f69bda73fce6b49b..3b4fb07a7bbdc31af56abd0069f397d9b431cd58 100644 (file)
@@ -28,6 +28,7 @@
 #include <QtGlobal>             // for qRound64, qint64
 
 #include "defs.h"
+#include "grtcirc.h"            // for gcdist, radtometers
 #include "src/core/datetime.h"  // for DateTime
 
 #if FILTERS_ENABLED
@@ -74,7 +75,7 @@ void PositionFilter::position_runqueue(const WaypointList& waypt_list, int qtype
           }
         }
 
-        if (something_deleted && (purge_duplicates != nullptr)) {
+        if (something_deleted && purge_duplicates) {
           qlist.at(i).wpt->wpt_flags.marked_for_deletion = 1;
         }
       }
index 4c22041725214627f5635c455c7b750d88446c1c..8ce40dec8bf6c1e87177962d4c0d392fef622445 100644 (file)
 #ifndef POSITION_H_INCLUDED_
 #define POSITION_H_INCLUDED_
 
+#include <QList>     // for QList
 #include <QString>    // for QString
 #include <QVector>    // for QVector
 #include <QtGlobal>   // for qint64
 
 #include "defs.h"     // for arglist_t, route_head (ptr only), ARG_NOMINMAX, ARGTYPE_FLOAT, ARGTYPE_REQUIRED, ARGTYPE_BOOL, Waypoint, WaypointList (ptr only)
 #include "filter.h"   // for Filter
-#include "grtcirc.h"  // for RAD, gcdist, radtometers
+#include "option.h"  // for OptionCString, OptionBool
 
 
 #if FILTERS_ENABLED
@@ -63,9 +64,9 @@ private:
 
   double pos_dist{};
   qint64 max_diff_time{};
-  char* distopt = nullptr;
-  char* timeopt = nullptr;
-  char* purge_duplicates = nullptr;
+  OptionCString distopt;
+  OptionCString timeopt;
+  OptionBool purge_duplicates;
   bool check_time{};
 
   QVector<arglist_t> args = {
index 7e978970ba0b2cb9c0886401c146f3a73493c9a1..d261d94a48bda61cd3e3ecbc1c81d4d4e35b14fa 100644 (file)
--- a/radius.cc
+++ b/radius.cc
@@ -28,6 +28,7 @@
 #include <QtGlobal>         // QAddConst<>::Type, foreach
 
 #include "defs.h"           // for Waypoint, del_marked_wpts, route_add_head, route_add_wpt, waypt_add, waypt_sort, waypt_swap, xstrtoi, route_head, WaypointList, kMilesPerKilometer
+#include "grtcirc.h"         // for gcdist, radtomiles
 
 
 #if FILTERS_ENABLED
@@ -38,7 +39,7 @@ void RadiusFilter::process()
     double dist = radtomiles(gcdist(waypointp->position(),
                                     home_pos->position()));
 
-    if ((dist >= pos_dist) == (exclopt == nullptr)) {
+    if ((dist >= pos_dist) == !exclopt) {
       waypointp->wpt_flags.marked_for_deletion = 1;
     } else {
       auto* ed = new extra_data;
@@ -48,7 +49,7 @@ void RadiusFilter::process()
   }
   del_marked_wpts();
 
-  if (nosort == nullptr) {
+  if (!nosort) {
     auto dist_comp_lambda = [](const Waypoint* a, const Waypoint* b)->bool {
       const auto* aed = static_cast<const extra_data*>(a->extra_data);
       const auto* bed = static_cast<const extra_data*>(b->extra_data);
index 3e18953c9f301abd496388dc2f31bb320c634ded..5c99c995a4aa503737eb1230a91c2343d8454287 100644 (file)
--- a/radius.h
+++ b/radius.h
 #ifndef RADIUS_H_INCLUDED_
 #define RADIUS_H_INCLUDED_
 
+#include <QList>     // for QList
 #include <QString>    // for QString
 #include <QVector>    // for QVector
 
 #include "defs.h"     // for arglist_t, ARG_NOMINMAX, ARGTYPE_FLOAT, ARGTYPE_REQUIRED, ARGTYPE_BOOL, ARGTYPE_INT, ARGTYPE_STRING, Waypoint
 #include "filter.h"   // for Filter
-#include "grtcirc.h"  // for RAD, gcdist, radtomiles
+#include "option.h"  // for OptionCString, OptionBool
 
 #if FILTERS_ENABLED
 
@@ -54,13 +55,13 @@ private:
   /* Data Members */
 
   double pos_dist{};
-  char* distopt = nullptr;
-  char* latopt = nullptr;
-  char* lonopt = nullptr;
-  char* exclopt = nullptr;
-  char* nosort = nullptr;
-  char* maxctarg = nullptr;
-  char* routename = nullptr;
+  OptionCString distopt;
+  OptionCString latopt;
+  OptionCString lonopt;
+  OptionBool exclopt;
+  OptionBool nosort;
+  OptionCString maxctarg;
+  OptionCString routename;
   int maxct{};
 
   Waypoint* home_pos{};
index d9ace300597332ace29b102feb0952c796317ec7..99b5ac60ab740c3ba13a5c3a723c6f1a93999a64 100644 (file)
--- a/random.h
+++ b/random.h
 #ifndef RANDOM_H_INCLUDED_
 #define RANDOM_H_INCLUDED_
 
-#include <random>            // for mt19937
+#include <random>     // for mt19937
 
-#include <QDateTime>         // for QDateTime
-#include <QString>           // for QString
-#include <QVector>           // for QVector
+#include <QList>      // for QList
+#include <QDateTime>  // for QDateTime
+#include <QString>    // for QString
+#include <QVector>    // for QVector
 
 #include "defs.h"
-#include "format.h"
+#include "format.h"   // for Format
+#include "option.h"   // for OptionCString, OptionBool
 
 
 class RandomFormat : public Format
@@ -82,9 +84,9 @@ private:
 
   /* Data Members */
 
-  char* opt_points{nullptr};
-  char* opt_seed{nullptr};
-  char* opt_nodelay{nullptr};
+  OptionCString opt_points;
+  OptionCString opt_seed;
+  OptionBool opt_nodelay;
 
   QVector<arglist_t> random_args = {
     {
index 9545f187d36ef8aa619c018940cf4ad80de38978..b7dae03465013259f01d2f9f4a0ad311ef7e90b7 100644 (file)
 
 #include <tuple>               // for tuple
 
+#include <QList>               // for QList
 #include <QString>             // for QString
 #include <QVector>             // for QVector
 
 #include "defs.h"              // for arglist_t, ARGTYPE_INT, Waypoint, route_head
 #include "filter.h"            // for Filter
+#include "option.h"            // for OptionCString
 #include "src/core/nvector.h"  // for NVector
 
 
@@ -67,9 +69,9 @@ private:
   int decimate_count{0};
   int interpolate_count{0};
 
-  char* decimateopt{nullptr};
-  char* interpolateopt{nullptr};
-  char* averageopt{nullptr};
+  OptionCString decimateopt;
+  OptionCString interpolateopt;
+  OptionCString averageopt;
 
   QVector<arglist_t> args = {
     {
diff --git a/shape.h b/shape.h
index 04b59a0dba03d0a00b831dfe3c9bd32785a9224b..b65417f6ba0cc96ff97713b6d2ad92f7e17d4594 100644 (file)
--- a/shape.h
+++ b/shape.h
 #ifndef SHAPE_H_INCLUDED_
 #define SHAPE_H_INCLUDED_
 
+#include <QList>               // for QList
 #include <QString>              // for QString
 #include <QVector>              // for QVector
 
 #include "defs.h"               // for arglist_t, ARGTYPE_STRING, Waypoint, route_head, FF_CAP_RW_ALL, ff_cap, ff_type, ff_type_file
 #include "format.h"             // for Format
+#include "option.h"            // for OptionCString
 #if SHAPELIB_ENABLED
 #if HAVE_LIBSHAPE
 #  include <shapefil.h>
@@ -86,8 +88,8 @@ private:
   QString ofname;
   int nameFieldIdx{};  // the field index of the field with fieldName "name" in the output DBF.
 
-  char* opt_name = nullptr;
-  char* opt_url = nullptr;
+  OptionCString opt_name;
+  OptionCString opt_url;
 
   QVector<arglist_t> shp_args = {
     {
index 2b272136757f761e7b4f185f8beab1f08c434078..2e13c9f89ef7b8be82fdd4183081b3d0ae838d29 100644 (file)
@@ -992,7 +992,7 @@ SkytraqBase::skytraq_read_tracks() const
   // m.ad/090930: removed code that tried reducing read_at_once if necessary since doesn't work with xmalloc
 
   if (opt_dump_file) {
-    dumpfile = gbfopen(opt_dump_file, "w", MYNAME);
+    dumpfile = gbfopen(opt_dump_file.get(), "w", MYNAME);
   }
 
   db(1, MYNAME ": Reading log data from device...\n");
@@ -1041,7 +1041,7 @@ SkytraqBase::skytraq_read_tracks() const
       gbfwrite(buffer, SECTOR_SIZE, got_sectors, dumpfile);
     }
 
-    if (*opt_no_output == '1') {
+    if (opt_no_output) {
       continue;                // skip decoding
     }
 
@@ -1164,7 +1164,7 @@ SkytraqBase::skytraq_set_location() const
   uint8_t MSG_SET_LOCATION[17] = { 0x36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   uint8_t MSG_GET_LOCATION = 0x35;
 
-  db(3, MYNAME ": set_location='%s'\n", opt_set_location);
+  db(3, MYNAME ": set_location='%s'\n", qPrintable(opt_set_location.get()));
 
   sscanf(opt_set_location, "%lf:%lf", &lat, &lng);
   le_write_double(&MSG_SET_LOCATION[1], lat);
@@ -1223,12 +1223,12 @@ SkytraqBase::skytraq_read() const
     skytraq_set_baud(dlbaud);
   }
 
-  // read device unless no-output=1 and dump-file=0 (i.e. no data needed at all)
-  if (*opt_no_output == '0'  ||  opt_dump_file != nullptr) {
+  // read device unless no-output=true and dump-file=0 (i.e. no data needed at all)
+  if (!opt_no_output ||  opt_dump_file != nullptr) {
     skytraq_read_tracks();
   }
 
-  if (*opt_erase == '1') {
+  if (opt_erase) {
     skytraq_erase();
   }
 
@@ -1431,7 +1431,7 @@ int MinihomerFormat::miniHomer_set_poi(uint16_t poinum, const char* opt_poi) con
 void
 MinihomerFormat::rd_init(const QString& fname)
 {
-  opt_set_location=nullptr;    // otherwise it will lead to bus error
+  opt_set_location.reset();    // otherwise it will lead to bus error
   skytraq_rd_init(fname);      // sets global var serial_handle
   mhport=fname;
 }
index 7c400f32b8c7aebba850f34d3ad3ce9dea3169eb..291cb25507dec63baa4ff2f382ebdef0e9a22228 100644 (file)
--- a/skytraq.h
+++ b/skytraq.h
@@ -25,6 +25,7 @@
 #ifndef SKYTRAQ_H_INCLUDED_
 #define SKYTRAQ_H_INCLUDED_
 
+#include <QList>      // for QList
 #include <QDateTime>  // for QDateTime
 #include <QString>    // for QString
 #include <QVector>    // for QVector
@@ -34,6 +35,7 @@
 #include "defs.h"
 #include "format.h"   // for Format
 #include "gbfile.h"   // for gbfile
+#include "option.h"   // for OptionCString, OptionBool
 
 
 class SkytraqBase
@@ -149,18 +151,18 @@ protected:
   void* serial_handle = nullptr;               /* IO file descriptor */
   int skytraq_baud = 0;                /* detected baud rate */
 
-  char* opt_erase = nullptr;           /* erase after read? (0/1) */
-  char* opt_initbaud = nullptr;                /* baud rate used to init device */
-  char* opt_dlbaud = nullptr;          /* baud rate used for downloading tracks */
-  char* opt_read_at_once = nullptr;    /* number of sectors to read at once (Venus6 only) */
-  char* opt_first_sector = nullptr;    /* first sector to be read from the device (default: 0) */
-  char* opt_last_sector = nullptr;     /* last sector to be read from the device (default: smart read everything) */
-  char* opt_dump_file = nullptr;               /* dump raw data to this file (optional) */
-  char* opt_no_output = nullptr;               /* disable output? (0/1) */
-  char* opt_set_location = nullptr;    /* set if the "targetlocation" options was used */
-  char* opt_configure_logging = nullptr;
-  char* opt_gps_utc_offset = nullptr;
-  char* opt_gps_week_rollover = nullptr;
+  OptionBool    opt_erase;             /* erase after read? (0/1) */
+  OptionCString opt_initbaud;          /* baud rate used to init device */
+  OptionCString opt_dlbaud;            /* baud rate used for downloading tracks */
+  OptionCString opt_read_at_once;      /* number of sectors to read at once (Venus6 only) */
+  OptionCString opt_first_sector;      /* first sector to be read from the device (default: 0) */
+  OptionCString opt_last_sector;       /* last sector to be read from the device (default: smart read everything) */
+  OptionCString opt_dump_file;         /* dump raw data to this file (optional) */
+  OptionBool    opt_no_output;         /* disable output? (0/1) */
+  OptionCString opt_set_location;      /* set if the "targetlocation" options was used */
+  OptionCString opt_configure_logging;
+  OptionCString opt_gps_utc_offset;
+  OptionCString opt_gps_week_rollover;
 };
 
 class SkytraqFormat : public Format, private SkytraqBase
@@ -339,11 +341,11 @@ private:
 
   /* Data Members */
 
-  char* opt_set_poi_home = nullptr;    /* set if a "poi" option was used */
-  char* opt_set_poi_car = nullptr;     /* set if a "poi" option was used */
-  char* opt_set_poi_boat = nullptr;    /* set if a "poi" option was used */
-  char* opt_set_poi_heart = nullptr;   /* set if a "poi" option was used */
-  char* opt_set_poi_bar = nullptr;     /* set if a "poi" option was used */
+  OptionCString opt_set_poi_home;      /* set if a "poi" option was used */
+  OptionCString opt_set_poi_car;       /* set if a "poi" option was used */
+  OptionCString opt_set_poi_boat;      /* set if a "poi" option was used */
+  OptionCString opt_set_poi_heart;     /* set if a "poi" option was used */
+  OptionCString opt_set_poi_bar;       /* set if a "poi" option was used */
 
   QVector<arglist_t> miniHomer_args = {
     { "baud",         &opt_dlbaud,        "Baud rate used for download", "115200", ARGTYPE_INT, "0", "115200", nullptr },
index c8d46ef2feb6b88ca6f4d02e147e418a19c6bb1b..4954e8536d5d3d27c7cee5fcd8a62fe59aab7064 100644 (file)
 #ifndef SMPLROUT_H_INCLUDED_
 #define SMPLROUT_H_INCLUDED_
 
+#include <QList>     // for QList
 #include <QString>               // for QString
-#include <QStringView>           // for QStringView
 #include <QVector>               // for QVector
 
 #include "defs.h"
-#include "filter.h"              // for Filter
+#include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool, OptionCString
 
 
 #if FILTERS_ENABLED
@@ -118,11 +119,11 @@ private:
   limit_basis_t limit_basis{limit_basis_t::error};
   metric_t metric{metric_t::crosstrack};
 
-  char* countopt = nullptr;
-  char* erroropt = nullptr;
-  char* xteopt = nullptr;
-  char* lenopt = nullptr;
-  char* relopt = nullptr;
+  OptionCString countopt;
+  OptionCString erroropt;
+  OptionBool xteopt;
+  OptionBool lenopt;
+  OptionBool relopt;
 
   QVector<arglist_t> args = {
     {
diff --git a/sort.h b/sort.h
index 81d64a660818c520372ee7df2dffa4d588cf41ea..c2de5be74213aeacf4509a5ad26c35da1abf8aca 100644 (file)
--- a/sort.h
+++ b/sort.h
 #ifndef SORT_H_INCLUDED_
 #define SORT_H_INCLUDED_
 
+#include <QList>     // for QList
 #include <QString>   // for QString
 #include <QVector>   // for QVector
 
 #include "defs.h"    // for arglist_t, ARGTYPE_BOOL, ARG_NOMINMAX, Waypoint
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool
 
 
 #if FILTERS_ENABLED
@@ -79,16 +81,16 @@ private:
   SortModeRteHd rte_sort_mode{SortModeRteHd::none};    /* How are we sorting these? */
   SortModeRteHd trk_sort_mode{SortModeRteHd::none};    /* How are we sorting these? */
 
-  char* opt_sm_gcid{};
-  char* opt_sm_shortname{};
-  char* opt_sm_description{};
-  char* opt_sm_time{};
-  char* opt_sm_rtenum{};
-  char* opt_sm_rtename{};
-  char* opt_sm_rtedesc{};
-  char* opt_sm_trknum{};
-  char* opt_sm_trkname{};
-  char* opt_sm_trkdesc{};
+  OptionBool opt_sm_gcid;
+  OptionBool opt_sm_shortname;
+  OptionBool opt_sm_description;
+  OptionBool opt_sm_time;
+  OptionBool opt_sm_rtenum;
+  OptionBool opt_sm_rtename;
+  OptionBool opt_sm_rtedesc;
+  OptionBool opt_sm_trknum;
+  OptionBool opt_sm_trkname;
+  OptionBool opt_sm_trkdesc;
 
   QVector<arglist_t> args = {
     {
index 2b2a70ecb8068ce0669af26f9158ca1249a0b995..7418275e5caf8d1dddc6bfcdfbf0d9cbf65f25f5 100644 (file)
 #ifndef STACKFILTER_H_INCLUDED_
 #define STACKFILTER_H_INCLUDED_
 
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
 #include "defs.h"    // for ARGTYPE_BOOL, ARG_NOMINMAX, ARGTYPE_BEGIN_EXCL
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool, OptionCString
 
 #if FILTERS_ENABLED
 
@@ -42,15 +45,15 @@ public:
   void exit() override;
 
 private:
-  char* opt_push = nullptr;
-  char* opt_copy = nullptr;
-  char* opt_pop = nullptr;
-  char* opt_append = nullptr;
-  char* opt_discard = nullptr;
-  char* opt_replace = nullptr;
-  char* opt_swap = nullptr;
-  char* opt_depth = nullptr;
-  char* nowarn = nullptr;
+  OptionBool opt_push;
+  OptionBool opt_copy;
+  OptionBool opt_pop;
+  OptionBool opt_append;
+  OptionBool opt_discard;
+  OptionBool opt_replace;
+  OptionBool opt_swap;
+  OptionCString opt_depth;
+  OptionBool nowarn;
   int  warnings_enabled = 1;
   int  swapdepth = 0;
 
index 062e690b456b354b1c117acae1f5c39b164b81a6..5b6ef91d5dc50f205cd9892f620007c81ac40ded 100644 (file)
--- a/subrip.cc
+++ b/subrip.cc
@@ -78,7 +78,7 @@ SubripFormat::subrip_prevwp_pr(const Waypoint* waypointp)
             starttime.hour(), starttime.minute(), starttime.second(), starttime.msec(),
             endtime.hour(), endtime.minute(), endtime.second(), endtime.msec());
 
-  for (char* c = opt_format; *c != '\0' ; c++) {
+  for (const char* c = static_cast<const char*>(opt_format); *c != '\0' ; c++) {
     char fmt;
 
     switch (*c) {
@@ -210,13 +210,13 @@ SubripFormat::wr_init(const QString& fname)
   }
   gps_datetime = QDateTime();
   if ((opt_gpstime != nullptr) && (opt_gpsdate != nullptr)) {
-    QDate gps_date = QDate::fromString(opt_gpsdate, u"yyyyMMdd");
+    QDate gps_date = QDate::fromString(opt_gpsdate.get(), u"yyyyMMdd");
     if (!gps_date.isValid()) {
       fatal(FatalMsg().nospace() << MYNAME ": option gps_date value (" << opt_gpsdate << ") is invalid.  Expected yyyymmdd.");
     }
-    QTime gps_time = QTime::fromString(opt_gpstime, u"HHmmss");
+    QTime gps_time = QTime::fromString(opt_gpstime.get(), u"HHmmss");
     if (!gps_time.isValid()) {
-      gps_time = QTime::fromString(opt_gpstime, u"HHmmss.z");
+      gps_time = QTime::fromString(opt_gpstime.get(), u"HHmmss.z");
       if (!gps_time.isValid()) {
         fatal(FatalMsg().nospace() << MYNAME ": option gps_time value (" << opt_gpstime << ") is invalid.  Expected hhmmss[.sss]");
       }
@@ -226,9 +226,9 @@ SubripFormat::wr_init(const QString& fname)
 
   video_offset_ms = 0;
   if (opt_videotime != nullptr) {
-    QTime video_time = QTime::fromString(opt_videotime, u"HHmmss");
+    QTime video_time = QTime::fromString(opt_videotime.get(), u"HHmmss");
     if (!video_time.isValid()) {
-      video_time = QTime::fromString(opt_videotime, u"HHmmss.z");
+      video_time = QTime::fromString(opt_videotime.get(), u"HHmmss.z");
       if (!video_time.isValid()) {
         fatal(FatalMsg().nospace() << MYNAME ": option video_time value (" << opt_videotime << ") is invalid.  Expected hhmmss[.sss].");
       }
index 5a43ae37467ba96a7b7f15bec0d63fb6f195793b..018a88ca206924be8ce49d80d41692d96cb82c34 100644 (file)
--- a/subrip.h
+++ b/subrip.h
 #ifndef SUBRIP_H_INCLUDED_
 #define SUBRIP_H_INCLUDED_
 
-#include <QDateTime>         // for QDateTime, operator<<
-#include <QString>           // for QString
-#include <QTime>             // for QTime
-#include <QVector>           // for QVector
+#include <QList>      // for QList
+#include <QDateTime>  // for QDateTime, operator<<
+#include <QString>    // for QString
+#include <QTime>      // for QTime
+#include <QVector>    // for QVector
 
 #include "defs.h"
-#include "format.h"          // for Format
-#include "gbfile.h"          // for gbfprintf, gbfclose, gbfopen, gbfwrite, gbfile
+#include "format.h"   // for Format
+#include "gbfile.h"   // for gbfprintf, gbfclose, gbfopen, gbfwrite, gbfile
+#include "option.h"   // for OptionCString
 
 
 class SubripFormat : public Format
@@ -63,10 +65,10 @@ private:
 
   /* Data Members */
 
-  char* opt_videotime{nullptr};
-  char* opt_gpstime{nullptr};
-  char* opt_gpsdate{nullptr};
-  char* opt_format{nullptr};
+  OptionCString opt_videotime;
+  OptionCString opt_gpstime;
+  OptionCString opt_gpsdate;
+  OptionCString opt_format;
   QDateTime gps_datetime;    // Date time corresponding to video video_offset_ms
   QDateTime video_datetime;  // Date time corresponding to video time 00:00:00,000.
   int video_offset_ms{0};
diff --git a/text.h b/text.h
index 37ad2b97dba5dee5f3505d4c3bd820d51f7aa381..69487256f3abf331764bb22a5dab9bf9c605a296 100644 (file)
--- a/text.h
+++ b/text.h
 #ifndef TEXT_H_INCLUDED_
 #define TEXT_H_INCLUDED_
 
+#include <QList>                  // for QList
 #include <QString>                // for QString
 #include <QVector>                // for QVector
 
 #include "defs.h"
 #include "format.h"               // for Format
 #include "mkshort.h"              // for MakeShort
+#include "option.h"               // for OptionBool, OptionCString
 #include "src/core/textstream.h"  // for TextStream
 
 
@@ -63,12 +65,12 @@ private:
   gpsbabel::TextStream* file_out{nullptr};
   MakeShort* mkshort_handle{};
 
-  char* suppresssep = nullptr;
-  char* txt_encrypt = nullptr;
-  char* includelogs = nullptr;
-  char* degformat = nullptr;
-  char* altunits = nullptr;
-  char* split_output = nullptr;
+  OptionBool suppresssep;
+  OptionBool txt_encrypt;
+  OptionBool includelogs;
+  OptionCString degformat;
+  OptionCString altunits;
+  OptionBool split_output;
   int waypoint_count{};
   QString output_name;
 
diff --git a/tpg.cc b/tpg.cc
index 3fde1c2b75dcb66265eca29c192c7a85135e2c13..b1c25b63548b6a3fbcf0aba0397aa2d49e6cfa28 100644 (file)
--- a/tpg.cc
+++ b/tpg.cc
@@ -61,7 +61,7 @@ TpgFormat::tpg_common_init()
 {
   tpg_datum_idx = GPS_Lookup_Datum_Index(tpg_datum_opt);
   if (tpg_datum_idx < 0) {
-    fatal(MYNAME ": Datum '%s' is not recognized.\n", tpg_datum_opt);
+    fatal(MYNAME ": Datum '%s' is not recognized.\n", qPrintable(tpg_datum_opt.get()));
   }
 }
 
diff --git a/tpg.h b/tpg.h
index 0fa129b3b61ae0aa9f68b93e04da699c30c01184..088fbab105eef9bb3cb1ab0557305976b1539f28 100644 (file)
--- a/tpg.h
+++ b/tpg.h
@@ -24,6 +24,7 @@
 #ifndef TPG_H_INCLUDED_
 #define TPG_H_INCLUDED_
 
+#include <QList>      // for QList
 #include <QString>    // for QString
 #include <QVector>    // for QVector
 
@@ -31,6 +32,7 @@
 #include "format.h"   // for Format
 #include "gbfile.h"   // for gbfile
 #include "mkshort.h"  // for MakeShort
+#include "option.h"   // for OptionCString
 
 
 class TpgFormat : public Format
@@ -72,7 +74,7 @@ private:
   gbfile* tpg_file_in{};
   gbfile* tpg_file_out{};
   MakeShort* mkshort_handle{};
-  char* tpg_datum_opt{};
+  OptionCString tpg_datum_opt;
   int tpg_datum_idx{};
 
   int waypt_out_count{};
index 835cd60999b94705add53d705c9fe98d34597ff0..d36d3cfe1d880db4392d7a2bc248ea357e7ed9ff 100644 (file)
@@ -67,7 +67,7 @@ int TrackFilter::trackfilter_opt_count()
   int res = 0;
 
   for (const auto& arg : std::as_const(args)) {
-    if (*arg.argval != nullptr) {
+    if (arg.argval->has_value()) {
       res++;
     }
   }
@@ -141,23 +141,23 @@ fix_type TrackFilter::trackfilter_parse_fix(int* nsats)
   if (!opt_fix) {
     return fix_unknown;
   }
-  if (!case_ignore_strcmp(opt_fix, "pps")) {
+  if (!case_ignore_strcmp(opt_fix.get(), "pps")) {
     *nsats = 4;
     return fix_pps;
   }
-  if (!case_ignore_strcmp(opt_fix, "dgps")) {
+  if (!case_ignore_strcmp(opt_fix.get(), "dgps")) {
     *nsats = 4;
     return fix_dgps;
   }
-  if (!case_ignore_strcmp(opt_fix, "3d")) {
+  if (!case_ignore_strcmp(opt_fix.get(), "3d")) {
     *nsats = 4;
     return fix_3d;
   }
-  if (!case_ignore_strcmp(opt_fix, "2d")) {
+  if (!case_ignore_strcmp(opt_fix.get(), "2d")) {
     *nsats = 3;
     return fix_2d;
   }
-  if (!case_ignore_strcmp(opt_fix, "none")) {
+  if (!case_ignore_strcmp(opt_fix.get(), "none")) {
     *nsats = 0;
     return fix_none;
   }
@@ -192,7 +192,7 @@ void TrackFilter::trackfilter_fill_track_list_cb(const route_head* track)   /* ca
   }
 
   if (opt_name != nullptr) {
-    QRegularExpression regex(QRegularExpression::wildcardToRegularExpression(opt_name),
+    QRegularExpression regex(QRegularExpression::wildcardToRegularExpression(opt_name.get()),
                              QRegularExpression::CaseInsensitiveOption);
     if (!regex.isValid()) {
       fatal(FatalMsg() << "track: name option is an invalid expression.");
@@ -256,7 +256,7 @@ void TrackFilter::trackfilter_split_init_rte_name(route_head* track, const gpsba
       strftime(buff, sizeof(buff), opt_title, &tm);
       track->rte_name = buff;
     } else {
-      track->rte_name = QStringLiteral("%1-%2").arg(opt_title, datetimestring);
+      track->rte_name = QStringLiteral("%1-%2").arg(opt_title.get(), datetimestring);
     }
   } else if (!track->rte_name.isEmpty()) {
     track->rte_name = QStringLiteral("%1-%2").arg(track->rte_name, datetimestring);
@@ -439,7 +439,7 @@ void TrackFilter::trackfilter_split()
     if (opt_interval != 0) {
       static const QRegularExpression re(R"(^([+-]?(?:\d+(?:\.\d*)?|\.\d+))([dhms])$)", QRegularExpression::CaseInsensitiveOption);
       assert(re.isValid());
-      QRegularExpressionMatch match = re.match(opt_split);
+      QRegularExpressionMatch match = re.match(opt_split.get());
       if (match.hasMatch()) {
         bool ok;
         interval = match.captured(1).toDouble(&ok);
@@ -467,7 +467,7 @@ void TrackFilter::trackfilter_split()
           printf(MYNAME ": interval %f seconds\n", interval);
         }
       } else {
-        fatal(MYNAME ": invalid timer interval specified \"%s\", must be a positive number, followed by 'd' for days, 'h' for hours, 'm' for minutes or 's' for seconds.\n", opt_split);
+        fatal(MYNAME ": invalid timer interval specified \"%s\", must be a positive number, followed by 'd' for days, 'h' for hours, 'm' for minutes or 's' for seconds.\n", qPrintable(opt_split.get()));
       }
     }
 
@@ -475,7 +475,7 @@ void TrackFilter::trackfilter_split()
     if (opt_distance != 0) {
       static const QRegularExpression re(R"(^([+-]?(?:\d+(?:\.\d*)?|\.\d+))([km])$)", QRegularExpression::CaseInsensitiveOption);
       assert(re.isValid());
-      QRegularExpressionMatch match = re.match(opt_sdistance);
+      QRegularExpressionMatch match = re.match(opt_sdistance.get());
       if (match.hasMatch()) {
         bool ok;
         distance = match.captured(1).toDouble(&ok);
@@ -498,7 +498,7 @@ void TrackFilter::trackfilter_split()
           printf(MYNAME ": distance %f meters\n", distance);
         }
       } else {
-        fatal(MYNAME ": invalid distance specified \"%s\", must be a positive number followed by 'k' for kilometers or 'm' for miles.\n", opt_sdistance);
+        fatal(MYNAME ": invalid distance specified \"%s\", must be a positive number followed by 'k' for kilometers or 'm' for miles.\n", qPrintable(opt_sdistance.get()));
       }
     }
 
@@ -1074,7 +1074,7 @@ void TrackFilter::process()
     }
   }
 
-  if (opt_seg2trk != nullptr) {
+  if (opt_seg2trk) {
     trackfilter_seg2trk();
     // track_list may? now be invalid!
     if (--opts == 0) {
@@ -1086,7 +1086,7 @@ void TrackFilter::process()
     init();
   }
 
-  if (opt_trk2seg != nullptr) {
+  if (opt_trk2seg) {
     trackfilter_trk2seg();
     if (--opts == 0) {
       return;
@@ -1102,7 +1102,7 @@ void TrackFilter::process()
 
   bool something_done = false;
 
-  if ((opt_pack != nullptr) || (opts == -1)) { /* call our default option */
+  if (opt_pack || (opts == -1)) {      /* call our default option */
     trackfilter_pack();
     something_done = true;
   } else if (opt_merge != nullptr) {
index e00dffba3596e3b0754f292182c89bf7a0c9b7cc..70d8e5e28c6ab16c9553dbcdd1a005ba6c2d45f7 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "defs.h"               // for ARG_NOMINMAX, route_head (ptr only), ARG...
 #include "filter.h"             // for Filter
+#include "option.h"             // for OptionCString, OptionBool
 #include "src/core/datetime.h"  // for DateTime
 
 #if FILTERS_ENABLED || MINIMAL_FILTERS
@@ -107,24 +108,24 @@ private:
 
   /* Data Members */
 
-  char* opt_merge = nullptr;
-  char* opt_pack = nullptr;
-  char* opt_split = nullptr;
-  char* opt_sdistance = nullptr;
-  char* opt_move = nullptr;
-  char* opt_title = nullptr;
-  char* opt_start = nullptr;
-  char* opt_stop = nullptr;
-  char* opt_fix = nullptr;
-  char* opt_course = nullptr;
-  char* opt_speed = nullptr;
-  char* opt_name = nullptr;
-  char* opt_seg2trk = nullptr;
-  char* opt_trk2seg = nullptr;
-  char* opt_segment = nullptr;
-  char* opt_faketime = nullptr;
-  char* opt_discard = nullptr;
-  char* opt_minpoints = nullptr;
+  OptionCString opt_merge;
+  OptionBool opt_pack;
+  OptionCString opt_split;
+  OptionCString opt_sdistance;
+  OptionCString opt_move;
+  OptionCString opt_title;
+  OptionCString opt_start;
+  OptionCString opt_stop;
+  OptionCString opt_fix;
+  OptionBool opt_course;
+  OptionBool opt_speed;
+  OptionCString opt_name;
+  OptionBool opt_seg2trk;
+  OptionBool opt_trk2seg;
+  OptionBool opt_segment;
+  OptionCString opt_faketime;
+  OptionBool opt_discard;
+  OptionCString opt_minpoints;
   int minimum_points{0};
 
   QVector<arglist_t> args = {
index e8f3fff35b766dfdb84773b2ac228663232a4a5f..ed90e0d49433b249117b8a8d64b9ba5da12a67d5 100644 (file)
@@ -131,11 +131,11 @@ void TransformFilter::transform_tracks()
 
 void TransformFilter::process()
 {
-  timeless = opt_timeless && (*opt_timeless == '1');
+  timeless = opt_timeless;
 
-  bool delete_after = opt_delete && (*opt_delete == '1');
+  bool delete_after = opt_delete;
 
-  use_src_name = opt_rpt_name && (*opt_rpt_name == '1');
+  use_src_name = opt_rpt_name;
 
   name_digits = 3;
   if (rpt_name_digits && *rpt_name_digits) {
@@ -158,7 +158,7 @@ void TransformFilter::process()
       }
       break;
     default:
-      fatal(MYNAME ": Invalid option value (%s)!\n", opt_waypts);
+      fatal(MYNAME ": Invalid option value (%s)!\n", qPrintable(opt_waypts.get()));
     }
   }
   if (opt_routes != nullptr) {
@@ -177,7 +177,7 @@ void TransformFilter::process()
       }
       break;
     default:
-      fatal(MYNAME ": Invalid option value (%s)!\n", opt_routes);
+      fatal(MYNAME ": Invalid option value (%s)!\n", qPrintable(opt_routes.get()));
     }
   }
   if (opt_tracks != nullptr) {
@@ -196,7 +196,7 @@ void TransformFilter::process()
       }
       break;
     default:
-      fatal(MYNAME ": Invalid option value (%s)!\n", opt_tracks);
+      fatal(MYNAME ": Invalid option value (%s)!\n", qPrintable(opt_tracks.get()));
     }
   }
 }
index a4cc50559cc744689c39a61caa6851efc8d793a5..e992ba29ed3a210e547556ec7f5979ddbd81053a 100644 (file)
 #ifndef TRANSFORM_H_INCLUDED_
 #define TRANSFORM_H_INCLUDED_
 
-#include <QString>         // for QString
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
-#include "defs.h"          // for route_head (ptr only), ARG_NOMINMAX, ARGTY...
-#include "filter.h"        // for Filter
+#include "defs.h"    // for route_head (ptr only), ARG_NOMINMAX, ARGTY...
+#include "filter.h"  // for Filter
+#include "option.h"  // for OptionCString, OptionBool
 
 #if FILTERS_ENABLED
 
@@ -45,8 +47,13 @@ private:
   route_head* current_trk{};
   route_head* current_rte{};
 
-  char* opt_routes{}, *opt_tracks{}, *opt_waypts{}, *opt_delete{}, *rpt_name_digits{}, *opt_rpt_name{};
-  char* opt_timeless{};
+  OptionCString opt_routes;
+  OptionCString opt_tracks;
+  OptionCString opt_waypts;
+  OptionBool opt_delete;
+  OptionCString rpt_name_digits;
+  OptionBool opt_rpt_name;
+  OptionBool opt_timeless;
   bool timeless{};
   bool use_src_name{};
   QString current_namepart;
index 8f2622576d1ebe9d5b37878deef9d82c6f386225..2371fe373f09ebce5d01d225bdef8ef244b14765 100644 (file)
--- a/unicsv.h
+++ b/unicsv.h
@@ -26,6 +26,7 @@
 
 #include <QDate>                  // for QDate
 #include <QDateTime>              // for QDateTime
+#include <QList>                  // for QList
 #include <QString>                // for QString
 #include <QTime>                  // for QTime
 #include <QVector>                // for QVector
@@ -33,6 +34,7 @@
 #include "defs.h"
 #include "format.h"               // for Format
 #include "geocache.h"             // for Geocache, Geocache::status_t
+#include "option.h"               // for OptionCString, OptionBool
 #include "src/core/textstream.h"  // for TextStream
 
 
@@ -198,14 +200,14 @@ private:
   std::bitset<fld_terminator> unicsv_outp_flags;
   grid_type unicsv_grid_idx{grid_unknown};
   int unicsv_datum_idx{};
-  char* opt_datum{nullptr};
-  char* opt_grid{nullptr};
-  char* opt_utc{nullptr};
-  char* opt_filename{nullptr};
-  char* opt_format{nullptr};
-  char* opt_prec{nullptr};
-  char* opt_fields{nullptr};
-  char* opt_codec{nullptr};
+  OptionCString opt_datum;
+  OptionCString opt_grid;
+  OptionCString opt_utc;
+  OptionBool opt_filename;
+  OptionBool opt_format;
+  OptionCString opt_prec;
+  OptionCString opt_fields;
+  OptionCString opt_codec;
   int unicsv_waypt_ct{};
   char unicsv_detect{};
   int llprec{};
index 9c54f34ca85c8957fdd2826acfa5ec8c0b7052ef..e28e4a4977fe604b86f252c5803b9434a0c163cb 100644 (file)
@@ -60,8 +60,8 @@ void ValidateFilter::process()
   RteHdFunctor<ValidateFilter> validate_head_f(this, &ValidateFilter::validate_head);
   RteHdFunctor<ValidateFilter> validate_head_trl_f(this, &ValidateFilter::validate_head_trl);
 
-  debug = *opt_debug == '1';
-  checkempty = *opt_checkempty == '1';
+  debug = opt_debug;
+  checkempty = opt_checkempty;
 
   point_ct = 0;
   if (debug) {
index 8c81c85870224b292d297eb4afdc62dbd8588c3e..f12c99aa7eab415d7f1afc23b433989b6f352649 100644 (file)
 #ifndef VALIDATE_H_INCLUDED_
 #define VALIDATE_H_INCLUDED_
 
-#include <QVector>         // for QVector
+#include <QList>     // for QList
+#include <QString>   // for QString
+#include <QVector>   // for QVector
 
 #include "defs.h"    // for route_head (ptr only), ARGTYPE_BOOL, ARG_NOMINMAX
 #include "filter.h"  // for Filter
+#include "option.h"  // for OptionBool
 
 #if FILTERS_ENABLED
 
@@ -40,9 +43,9 @@ public:
   void process() override;
 
 private:
-  char* opt_debug{};
+  OptionBool opt_debug;
   bool debug{};
-  char* opt_checkempty{};
+  OptionBool opt_checkempty;
   bool checkempty{};
   int point_ct{};
   int total_point_ct{};
diff --git a/vcf.h b/vcf.h
index 7a4a53131c49690e473e218da757187a3fe3fa37..015f4e832608bd48a51ab13c7089cfe7ee87b068 100644 (file)
--- a/vcf.h
+++ b/vcf.h
@@ -20,6 +20,7 @@
 #ifndef VCF_H_INCLUDED_
 #define VCF_H_INCLUDED_
 
+#include <QList>       // for QList
 #include <QString>     // for QString
 #include <QVector>     // for QVector
 
@@ -27,6 +28,7 @@
 #include "format.h"    // for Format
 #include "gbfile.h"    // for gbfile
 #include "geocache.h"  // for Geocache
+#include "option.h"    // for OptionBool
 
 
 class VcfFormat : public Format
@@ -66,7 +68,7 @@ private:
 
   gbfile* file_out{};
 
-  char* vcf_encrypt = nullptr;
+  OptionBool vcf_encrypt;
 
   QVector<arglist_t> vcf_args = {
     {
diff --git a/vecs.cc b/vecs.cc
index 0218188cc756f4f0f318447b410a1a8417fcfaad..d21a988dc1bfc95859976b9c03072ce8bea6adec 100644 (file)
--- a/vecs.cc
+++ b/vecs.cc
@@ -39,7 +39,7 @@
 #include <type_traits>         // for is_base_of
 #include <utility>             // for as_const
 
-#include "defs.h"              // for arglist_t, ff_vecs_t, ff_cap, fatal, CSTR, ARGTYPE_TYPEMASK, case_ignore_strcmp, global_options, global_opts, warning, xfree, ARGTYPE_BOOL, ff_cap_read, ff_cap_write, ARGTYPE_HIDDEN, ff_type_internal, xstrdup, ARGTYPE_INT, ARGTYPE_REQUIRED, ARGTYPE_FLOAT
+#include "defs.h"              // for arglist_t, CSTR, fatal, ff_cap, ARGTYPE_TYPEMASK, ff_type, ARGTYPE_BOOL, case_ignore_strcmp, gpsdata_type, warning, ff_cap_array, global_options, global_opts, ARGTYPE_FLOAT, ARGTYPE_HIDDEN, ARGTYPE_INT, ARGTYPE_REQUIRED
 #include "dg-100.h"            // for Dg100FileFormat, Dg100SerialFormat, Dg200FileFormat, Dg200SerialFormat
 #include "exif.h"              // for ExifFormat
 #include "format.h"            // for Format
@@ -64,6 +64,7 @@
 #include "lowranceusr.h"       // for LowranceusrFormat
 #include "mtk_logger.h"        // for MtkFormat, MtkM241Format, MtkFileFormat, MtkM241FileFormat
 #include "nmea.h"              // for NmeaFormat
+#include "option.h"            // for Option, OptionBool
 #include "osm.h"               // for OsmFormat
 #include "ozi.h"               // for OziFormat
 #include "qstarz_bl_1000.h"    // for QstarzBL1000Format
@@ -507,9 +508,8 @@ void Vecs::init_vec(Format* fmt)
   if (args && !args->isEmpty()) {
     assert(args->isDetached());
     for (auto& arg : *args) {
-      arg.argvalptr = nullptr;
-      if (arg.argval) {
-        *arg.argval = nullptr;
+      if (arg.argval != nullptr) {
+        arg.argval->reset();
       }
     }
   }
@@ -590,9 +590,8 @@ void Vecs::free_options(QVector<arglist_t>* args)
   if (args && !args->isEmpty()) {
     assert(args->isDetached());
     for (auto& arg : *args) {
-      if (arg.argvalptr) {
-        xfree(arg.argvalptr);
-        *arg.argval = arg.argvalptr = nullptr;
+      if (arg.argval != nullptr) {
+        arg.argval->reset();
       }
     }
   }
@@ -615,19 +614,13 @@ void Vecs::exit_vecs()
   style_list.squeeze();
 }
 
-void Vecs::assign_option(const QString& module, arglist_t* arg, const QString& val)
+void Vecs::assign_option(const QString& module, arglist_t& arg, const QString& val)
 {
-  if (arg->argval == nullptr) {
-    fatal("%s: No local variable defined for option \"%s\"!\n", qPrintable(module), qPrintable(arg->argstring));
+  if (arg.argval == nullptr) {
+    fatal("%s: No local variable defined for option \"%s\"!\n", qPrintable(module), qPrintable(arg.argstring));
   }
 
-  if (arg->argvalptr != nullptr) {
-    xfree(arg->argvalptr);
-    arg->argvalptr = nullptr;
-  }
-  if (arg->argval) {
-    *arg->argval = nullptr;
-  }
+  arg.argval->reset();
 
   if (val.isNull()) {
     return;
@@ -635,13 +628,13 @@ void Vecs::assign_option(const QString& module, arglist_t* arg, const QString& v
 
   QString rval(val);
 
-  switch (arg->argtype & ARGTYPE_TYPEMASK) {
+  switch (arg.argtype & ARGTYPE_TYPEMASK) {
   case ARGTYPE_INT:
     if (val.isEmpty()) {
       rval = '0';
     } else {
       if (!is_integer(val)) {
-        fatal("%s: Invalid parameter value \"%s\" for option %s!\n", qPrintable(module), qPrintable(val), qPrintable(arg->argstring));
+        fatal("%s: Invalid parameter value \"%s\" for option %s!\n", qPrintable(module), qPrintable(val), qPrintable(arg.argstring));
       }
     }
     break;
@@ -650,7 +643,7 @@ void Vecs::assign_option(const QString& module, arglist_t* arg, const QString& v
       rval = '0';
     } else {
       if (!is_float(val)) {
-        fatal("%s: Invalid parameter value \"%s\" for option %s!\n", qPrintable(module), qPrintable(val), qPrintable(arg->argstring));
+        fatal("%s: Invalid parameter value \"%s\" for option %s!\n", qPrintable(module), qPrintable(val), qPrintable(arg.argstring));
       }
     }
     break;
@@ -671,7 +664,7 @@ void Vecs::assign_option(const QString& module, arglist_t* arg, const QString& v
             rval = '1';
           }
         } else {
-          warning("%s :Invalid logical value \"%s\" for option %s!\n", qPrintable(module), qPrintable(val), qPrintable(arg->argstring));
+          warning("%s :Invalid logical value \"%s\" for option %s!\n", qPrintable(module), qPrintable(val), qPrintable(arg.argstring));
           rval = '0';
         }
       }
@@ -679,23 +672,17 @@ void Vecs::assign_option(const QString& module, arglist_t* arg, const QString& v
     break;
   }
 
-  /* for bool options without default: don't set argval if "FALSE" */
-
-  if (((arg->argtype & ARGTYPE_TYPEMASK) == ARGTYPE_BOOL) &&
-      rval.startsWith('0') && (arg->defaultvalue == nullptr)) {
-    return;
-  }
-  *arg->argval = arg->argvalptr = xstrdup(CSTR(rval));
+  arg.argval->set(rval);
 }
 
 void Vecs::disp_vec_options(const QString& vecname, const QVector<arglist_t>* args)
 {
   if (args) {
     for (const auto& arg : *args) {
-      if (arg.argval && *arg.argval) {
+      if ((arg.argval != nullptr) && !arg.argval->isEmpty()) {
         printf("options: module/option=value: %s/%s=\"%s\"",
-               qPrintable(vecname), qPrintable(arg.argstring), *arg.argval);
-        if (case_ignore_strcmp(arg.defaultvalue, *arg.argval) == 0) {
+               qPrintable(vecname), qPrintable(arg.argstring), qPrintable(arg.argval->get()));
+        if (case_ignore_strcmp(arg.defaultvalue, arg.argval->get()) == 0) {
           printf(" (=default)");
         }
         printf("\n");
@@ -735,7 +722,7 @@ void Vecs::prepare_format(const fmtinfo_t& fmtdata)
       if (!fmtdata.options.isEmpty()) {
         const QString opt = get_option(fmtdata.options, arg.argstring);
         if (!opt.isNull()) {
-          assign_option(fmtdata.fmtname, &arg, opt);
+          assign_option(fmtdata.fmtname, arg, opt);
           continue;
         }
       }
@@ -744,9 +731,9 @@ void Vecs::prepare_format(const fmtinfo_t& fmtdata)
         qopt = inifile_readstr(global_opts.inifile, "Common format settings", arg.argstring);
       }
       if (qopt.isNull()) {
-        assign_option(fmtdata.fmtname, &arg, arg.defaultvalue);
+        assign_option(fmtdata.fmtname, arg, arg.defaultvalue);
       } else {
-        assign_option(fmtdata.fmtname, &arg, qopt);
+        assign_option(fmtdata.fmtname, arg, qopt);
       }
     }
   }
@@ -1137,6 +1124,10 @@ bool Vecs::validate_args(const QString& name, const QVector<arglist_t>* args)
     }
 #endif
     for (const auto& arg : *args) {
+      if (arg.argval == nullptr) {
+        Warning() << name << "option" << arg.argstring << "does not point to an Option instance.";
+        ok = false;
+      }
       if ((arg.argtype & ARGTYPE_TYPEMASK) == ARGTYPE_INT) {
         if (!arg.defaultvalue.isNull() && !is_integer(arg.defaultvalue)) {
           Warning() << name << "Int option" << arg.argstring << "default value" << arg.defaultvalue << "is not an integer.";
@@ -1176,6 +1167,16 @@ bool Vecs::validate_args(const QString& name, const QVector<arglist_t>* args)
           Warning() << name << "Bool option" << arg.argstring << "maximum value" << arg.maxvalue << "is not an bool.";
           ok = false;
         }
+        if (const auto* opt = dynamic_cast<const OptionBool*>(arg.argval); opt == nullptr) {
+          Warning() << name << "Bool option" << arg.argstring << "argval is not of class OptionBool";
+          ok = false;
+        }
+      }
+      if ((arg.argtype & ARGTYPE_TYPEMASK) != ARGTYPE_BOOL) {
+        if (const auto* opt = dynamic_cast<const OptionBool*>(arg.argval); opt != nullptr) {
+          Warning() << name << "non Bool option" << arg.argstring << "argval is of class OptionBool";
+          ok = false;
+        }
       }
     }
   }
diff --git a/vecs.h b/vecs.h
index 415f3b402b3038671899746573e2745f3f9afd63..f1be8f1a7ec58f80cce25054f5c14cc6b649c79b 100644 (file)
--- a/vecs.h
+++ b/vecs.h
@@ -76,7 +76,7 @@ public:
   static void free_options(QVector<arglist_t>* args);
   static void exit_vec(Format* fmt);
   void exit_vecs();
-  static void assign_option(const QString& module, arglist_t* arg, const QString& val);
+  static void assign_option(const QString& module, arglist_t& arg, const QString& val);
   static void disp_vec_options(const QString& vecname, const QVector<arglist_t>* args);
   static void validate_options(const QStringList& options, const QVector<arglist_t>* args, const QString& name);
   static QString get_option(const QStringList& options, const QString& argname);
diff --git a/xcsv.cc b/xcsv.cc
index 5f4c1ba301d41356dc2bd550300e895bc98ac741..74f94c65e15ce0782fca027721e25f38d5c486f5 100644 (file)
--- a/xcsv.cc
+++ b/xcsv.cc
@@ -1882,7 +1882,7 @@ XcsvFormat::rd_init(const QString& fname)
       fatal(MYNAME ": XCSV input style not declared.  Use ... -i xcsv,style=path/to/file.style\n");
     }
 
-    xcsv_style = new XcsvStyle(XcsvStyle::xcsv_read_style(styleopt));
+    xcsv_style = new XcsvStyle(XcsvStyle::xcsv_read_style(styleopt.get()));
   }
 
   if ((xcsv_style->datatype == 0) || (xcsv_style->datatype == wptdata)) {
@@ -1940,7 +1940,7 @@ XcsvFormat::wr_init(const QString& fname)
       fatal(MYNAME ": XCSV output style not declared.  Use ... -o xcsv,style=path/to/file.style\n");
     }
 
-    xcsv_style = new XcsvStyle(XcsvStyle::xcsv_read_style(styleopt));
+    xcsv_style = new XcsvStyle(XcsvStyle::xcsv_read_style(styleopt.get()));
   }
 
   xcsv_file = new XcsvFile;
@@ -1965,16 +1965,16 @@ XcsvFormat::wr_init(const QString& fname)
       xcsv_file->mkshort_handle.set_length(xstrtoi(snlenopt, nullptr, 10));
     }
 
-    if (snwhiteopt) {
-      xcsv_file->mkshort_handle.set_whitespace_ok(xstrtoi(snwhiteopt, nullptr, 10));
+    if (snwhiteopt.has_value()) {
+      xcsv_file->mkshort_handle.set_whitespace_ok(snwhiteopt);
     }
 
-    if (snupperopt) {
-      xcsv_file->mkshort_handle.set_mustupper(xstrtoi(snupperopt, nullptr, 10));
+    if (snupperopt.has_value()) {
+      xcsv_file->mkshort_handle.set_mustupper(snupperopt);
     }
 
-    if (snuniqueopt) {
-      xcsv_file->mkshort_handle.set_mustuniq(xstrtoi(snuniqueopt, nullptr, 10));
+    if (snuniqueopt.has_value()) {
+      xcsv_file->mkshort_handle.set_mustuniq(snuniqueopt);
     }
 
     xcsv_file->mkshort_handle.set_badchars(CSTR(xcsv_style->badchars));
diff --git a/xcsv.h b/xcsv.h
index c1fb2551b7950af26fa5d2ef588ff924a1f1d01b..d76ce8e1fc7fbf7a9fad38bb9bb89dc9a534048b 100644 (file)
--- a/xcsv.h
+++ b/xcsv.h
@@ -40,6 +40,7 @@
 #include "format.h"               // for Format
 #include "garmin_fs.h"            // for garmin_fs_t
 #include "mkshort.h"              // for MakeShort
+#include "option.h"               // for OptionCString, OptionBool
 #include "src/core/datetime.h"    // for DateTime
 #include "src/core/textstream.h"  // for TextStream
 
@@ -370,15 +371,15 @@ private:
   const route_head* csv_track = nullptr;
   const route_head* csv_route = nullptr;
 
-  char* styleopt = nullptr;
-  char* snlenopt = nullptr;
-  char* snwhiteopt = nullptr;
-  char* snupperopt = nullptr;
-  char* snuniqueopt = nullptr;
-  char* prefer_shortnames = nullptr;
-  char* xcsv_urlbase = nullptr;
-  char* opt_datum = nullptr;
-  char* opt_utc = nullptr;
+  OptionCString styleopt;
+  OptionCString snlenopt;
+  OptionBool snwhiteopt;
+  OptionBool snupperopt;
+  OptionBool snuniqueopt;
+  OptionBool prefer_shortnames;
+  OptionCString xcsv_urlbase;
+  OptionCString opt_datum;
+  OptionCString opt_utc;
   int utc_offset{};
 
   QString intstylefile;